Use less nesting in many arrays of arrays tests.
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gles31 / es31cArrayOfArraysTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-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 #include "es31cArrayOfArraysTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluDefs.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30
31 #include <algorithm>
32 #include <cassert>
33 #include <cstdio>
34 #include <string>
35 using std::string;
36
37 /* Selects if debug output is enabled */
38 #define IS_DEBUG 0
39 #define IS_DEBUG_DUMP_ALL_SHADERS 0
40
41 /* Selects if workaround in ExpressionsInvalid2 test is enabled */
42 #define WRKARD_EXPRESSIONSINVALID2 0
43
44 #if IS_DEBUG
45 #include "tcuTestLog.hpp"
46 #endif
47
48 namespace glcts
49 {
50 namespace ArraysOfArrays
51 {
52 namespace Interface
53 {
54 /* Sets limits on number of dimensions. Value 8 comes from ogirinal "ES" implementation.
55  * Explanation was as follows:
56  *
57  *     "The current specifations allow up to 8 array dimensions."
58  */
59 const size_t ES::MAX_ARRAY_DIMENSIONS = 8;
60 const size_t GL::MAX_ARRAY_DIMENSIONS = 8;
61
62 /* API specific shader parts */
63 const char* ES::shader_version_gpu5 =
64         "#version 310 es\n#extension GL_EXT_gpu_shader5 : require\nprecision mediump float;\n\n";
65 const char* ES::shader_version = "#version 310 es\nprecision mediump float;\n\n";
66
67 const char* GL::shader_version_gpu5 = "#version 430 core\n\n";
68 const char* GL::shader_version          = "#version 430 core\n\n";
69 } /* namespace Interface */
70
71 /* Dummy fragment shader source code.
72  * Used when testing the vertex shader. */
73 const std::string default_fragment_shader_source = "//default fragment shader\n"
74                                                                                                    "out vec4 color;\n"
75                                                                                                    "void main()\n"
76                                                                                                    "{\n"
77                                                                                                    "    color = vec4(1.0);\n"
78                                                                                                    "}\n";
79
80 /* Dummy vertex shader source code.
81  * Used when testing the fragment shader. */
82 const std::string default_vertex_shader_source = "//default vertex shader\n"
83                                                                                                  "\n"
84                                                                                                  "void main()\n"
85                                                                                                  "{\n"
86                                                                                                  "    gl_Position = vec4(0.0,0.0,0.0,1.0);\n"
87                                                                                                  "}\n";
88
89 /* Dummy geometry shader source code.
90  * Used when testing the other shaders. */
91 const std::string default_geometry_shader_source = "//default geometry\n"
92                                                                                                    "\n"
93                                                                                                    "void main()\n"
94                                                                                                    "{\n"
95                                                                                                    "    gl_Position  = vec4(-1, -1, 0, 1);\n"
96                                                                                                    "    EmitVertex();\n"
97                                                                                                    "    gl_Position  = vec4(-1, 1, 0, 1);\n"
98                                                                                                    "    EmitVertex();\n"
99                                                                                                    "    gl_Position  = vec4(1, -1, 0, 1);\n"
100                                                                                                    "    EmitVertex();\n"
101                                                                                                    "    gl_Position  = vec4(1, 1, 0, 1);\n"
102                                                                                                    "    EmitVertex();\n"
103                                                                                                    "}\n";
104
105 /* Dummy tesselation control shader source code.
106  * Used when testing the other shaders. */
107 const std::string default_tc_shader_source = "//default tcs\n"
108                                                                                          "\n"
109                                                                                          "void main()\n"
110                                                                                          "{\n"
111                                                                                          "    gl_TessLevelOuter[0] = 1.0;\n"
112                                                                                          "    gl_TessLevelOuter[1] = 1.0;\n"
113                                                                                          "    gl_TessLevelOuter[2] = 1.0;\n"
114                                                                                          "    gl_TessLevelOuter[3] = 1.0;\n"
115                                                                                          "    gl_TessLevelInner[0] = 1.0;\n"
116                                                                                          "    gl_TessLevelInner[1] = 1.0;\n"
117                                                                                          "}\n";
118
119 /* Dummy tesselation evaluation shader source code.
120  * Used when testing the other shaders. */
121 const std::string default_te_shader_source = "//default tes\n"
122                                                                                          "\n"
123                                                                                          "void main()\n"
124                                                                                          "{\n"
125                                                                                          "}\n";
126
127 /* Pass-through shaders source code. Used when testing other stage. */
128 const std::string pass_fragment_shader_source = "//pass fragment shader\n"
129                                                                                                 "in float fs_result;\n"
130                                                                                                 "out vec4 color;\n"
131                                                                                                 "\n"
132                                                                                                 "void main()\n"
133                                                                                                 "{\n"
134                                                                                                 "    color = vec4(fs_result);\n"
135                                                                                                 "}\n";
136
137 const std::string pass_geometry_shader_source = "//pass geometry\n"
138                                                                                                 "in  float gs_result[];\n"
139                                                                                                 "out float fs_result;\n"
140                                                                                                 "\n"
141                                                                                                 "void main()\n"
142                                                                                                 "{\n"
143                                                                                                 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
144                                                                                                 "    fs_result = gs_result[0];\n"
145                                                                                                 "    EmitVertex();\n"
146                                                                                                 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
147                                                                                                 "    fs_result = gs_result[0];\n"
148                                                                                                 "    EmitVertex();\n"
149                                                                                                 "    gl_Position  = vec4(1, -1, 0, 1);\n"
150                                                                                                 "    fs_result = gs_result[0];\n"
151                                                                                                 "    EmitVertex();\n"
152                                                                                                 "    gl_Position  = vec4(1, 1, 0, 1);\n"
153                                                                                                 "    fs_result = gs_result[0];\n"
154                                                                                                 "    EmitVertex();\n"
155                                                                                                 "}\n";
156
157 const std::string pass_te_shader_source = "//pass tes\n"
158                                                                                   "in  float tcs_result[];\n"
159                                                                                   "out float fs_result;\n"
160                                                                                   "\n"
161                                                                                   "void main()\n"
162                                                                                   "{\n"
163                                                                                   "    fs_result = tcs_result[0];\n"
164                                                                                   "}\n";
165
166 /* Empty string */
167 static const std::string empty_string = "";
168
169 /* Beginning of a shader source code. */
170 const std::string shader_start = "void main()\n"
171                                                                  "{\n";
172
173 /* End of a shader source code. */
174 const std::string shader_end = "}\n";
175
176 /* Emit full screen quad from GS */
177 const std::string emit_quad = "    gl_Position  = vec4(-1, -1, 0, 1);\n"
178                                                           "    EmitVertex();\n"
179                                                           "    gl_Position  = vec4(-1, 1, 0, 1);\n"
180                                                           "    EmitVertex();\n"
181                                                           "    gl_Position  = vec4(1, -1, 0, 1);\n"
182                                                           "    EmitVertex();\n"
183                                                           "    gl_Position  = vec4(1, 1, 0, 1);\n"
184                                                           "    EmitVertex();\n";
185
186 /* Set tesselation levels */
187 const std::string set_tesseation = "    gl_TessLevelOuter[0] = 1.0;\n"
188                                                                    "    gl_TessLevelOuter[1] = 1.0;\n"
189                                                                    "    gl_TessLevelOuter[2] = 1.0;\n"
190                                                                    "    gl_TessLevelOuter[3] = 1.0;\n"
191                                                                    "    gl_TessLevelInner[0] = 1.0;\n"
192                                                                    "    gl_TessLevelInner[1] = 1.0;\n";
193
194 /* Input and output data type modifiers. */
195 const std::string in_out_type_modifiers[] = { "in", "out", "uniform" };
196
197 /* Types and appropriate initialisers, used throughout these tests */
198 const var_descriptor var_descriptors[] = {
199         { "bool", "", "true", "false", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
200         { "int", "", "1", "0", "0", "int", "", "iterator", "1", "N/A", "N/A" },
201         { "uint", "", "1u", "0u", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
202         { "float", "", "1.0", "0.0", "0.0", "float", "", "iterator", "1.0", "N/A", "N/A" },
203         { "vec2", "", "vec2(1.0)", "vec2(0.0)", "0.0", "float", "[0]", "vec2(iterator)", "vec2(1.0)", "N/A", "N/A" },
204         { "vec3", "", "vec3(1.0)", "vec3(0.0)", "0.0", "float", "[0]", "vec3(iterator)", "vec3(1.0)", "N/A", "N/A" },
205         { "vec4", "", "vec4(1.0)", "vec4(0.0)", "0.0", "float", "[0]", "vec4(iterator)", "vec4(1.0)", "N/A", "N/A" },
206         { "bvec2", "", "bvec2(1)", "bvec2(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
207         { "bvec3", "", "bvec3(1)", "bvec3(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
208         { "bvec4", "", "bvec4(1)", "bvec4(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
209         { "ivec2", "", "ivec2(1)", "ivec2(0)", "0", "int", "[0]", "ivec2(iterator)", "ivec2(1)", "N/A", "N/A" },
210         { "ivec3", "", "ivec3(1)", "ivec3(0)", "0", "int", "[0]", "ivec3(iterator)", "ivec3(1)", "N/A", "N/A" },
211         { "ivec4", "", "ivec4(1)", "ivec4(0)", "0", "int", "[0]", "ivec4(iterator)", "ivec4(1)", "N/A", "N/A" },
212         { "uvec2", "", "uvec2(1u)", "uvec2(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
213         { "uvec3", "", "uvec3(1u)", "uvec3(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
214         { "uvec4", "", "uvec4(1u)", "uvec4(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
215         { "mat2", "", "mat2(1.0)", "mat2(0.0)", "0.0", "float", "[0][0]", "mat2(iterator)", "mat2(1.0)", "N/A", "N/A" },
216         { "mat3", "", "mat3(1.0)", "mat3(0.0)", "0.0", "float", "[0][0]", "mat3(iterator)", "mat3(1.0)", "N/A", "N/A" },
217         { "mat4", "", "mat4(1.0)", "mat4(0.0)", "0.0", "float", "[0][0]", "mat4(iterator)", "mat4(1.0)", "N/A", "N/A" },
218         { "mat2x2", "", "mat2x2(1.0)", "mat2x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
219         { "mat2x3", "", "mat2x3(1.0)", "mat2x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
220         { "mat2x4", "", "mat2x4(1.0)", "mat2x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
221         { "mat3x2", "", "mat3x2(1.0)", "mat3x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
222         { "mat3x3", "", "mat3x3(1.0)", "mat3x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
223         { "mat3x4", "", "mat3x4(1.0)", "mat3x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
224         { "mat4x2", "", "mat4x2(1.0)", "mat4x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
225         { "mat4x3", "", "mat4x3(1.0)", "mat4x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
226         { "mat4x4", "", "mat4x4(1.0)", "mat4x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
227         { "imageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
228         { "iimageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
229         { "uimageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
230         { "samplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
231         { "isamplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
232         { "usamplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
233         { "sampler2D", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "vec4" },
234         { "sampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" },
235         { "samplerCube", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" },
236         {
237                 "samplerCubeShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec4(0.0)", "float",
238         },
239         { "sampler2DShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "float" },
240         { "sampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" },
241         { "sampler2DArrayShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec4(0.0)", "float" },
242         { "isampler2D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "ivec4" },
243         { "isampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" },
244         { "isamplerCube", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" },
245         { "isampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" },
246         { "usampler2D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "uvec4" },
247         { "usampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" },
248         { "usamplerCube", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" },
249         { "usampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" },
250 };
251
252 const var_descriptor var_double_descriptors[] = {
253         { "double", "", "1.0", "0.0", "0.0", "double", "", "iterator", "1.0", "N/A", "N/A" },
254         { "dmat2", "", "dmat2(1.0)", "dmat2(0.0)", "0.0", "double", "[0][0]", "dmat2(iterator)", "dmat2(1.0)", "N/A",
255           "N/A" },
256         { "dmat3", "", "dmat3(1.0)", "dmat3(0.0)", "0.0", "double", "[0][0]", "dmat3(iterator)", "dmat3(1.0)", "N/A",
257           "N/A" },
258         { "dmat4", "", "dmat4(1.0)", "dmat4(0.0)", "0.0", "double", "[0][0]", "dmat4(iterator)", "dmat4(1.0)", "N/A",
259           "N/A" },
260         { "dmat2x2", "", "dmat2x2(1.0)", "dmat2x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
261         { "dmat2x3", "", "dmat2x3(1.0)", "dmat2x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
262         { "dmat2x4", "", "dmat2x4(1.0)", "dmat2x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
263         { "dmat3x2", "", "dmat3x2(1.0)", "dmat3x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
264         { "dmat3x3", "", "dmat3x3(1.0)", "dmat3x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
265         { "dmat3x4", "", "dmat3x4(1.0)", "dmat3x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
266         { "dmat4x2", "", "dmat4x2(1.0)", "dmat4x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
267         { "dmat4x3", "", "dmat4x3(1.0)", "dmat4x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
268         { "dmat4x4", "", "dmat4x4(1.0)", "dmat4x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
269 };
270
271 _supported_variable_types_map supported_variable_types_map;
272
273 /** List of all supported variable types for es. */
274 const test_var_type var_types_es[] = {
275         VAR_TYPE_BOOL,   VAR_TYPE_INT,  VAR_TYPE_UINT,   VAR_TYPE_FLOAT,  VAR_TYPE_VEC2,   VAR_TYPE_VEC3,
276         VAR_TYPE_VEC4,   VAR_TYPE_BVEC2,  VAR_TYPE_BVEC3,  VAR_TYPE_BVEC4,  VAR_TYPE_IVEC2,  VAR_TYPE_IVEC3,
277         VAR_TYPE_IVEC4,  VAR_TYPE_UVEC2,  VAR_TYPE_UVEC3,  VAR_TYPE_UVEC4,  VAR_TYPE_MAT2,   VAR_TYPE_MAT3,
278         VAR_TYPE_MAT4,   VAR_TYPE_MAT2X2, VAR_TYPE_MAT2X3, VAR_TYPE_MAT2X4, VAR_TYPE_MAT3X2, VAR_TYPE_MAT3X3,
279         VAR_TYPE_MAT3X4, VAR_TYPE_MAT4X2, VAR_TYPE_MAT4X3, VAR_TYPE_MAT4X4,
280 };
281
282 const test_var_type* Interface::ES::var_types   = var_types_es;
283 const size_t             Interface::ES::n_var_types = sizeof(var_types_es) / sizeof(var_types_es[0]);
284
285 /** List of all supported variable types for gl. */
286 static const glcts::test_var_type var_types_gl[] = {
287         VAR_TYPE_BOOL,  VAR_TYPE_INT,           VAR_TYPE_UINT,  VAR_TYPE_FLOAT,   VAR_TYPE_VEC2,        VAR_TYPE_VEC3,
288         VAR_TYPE_VEC4,  VAR_TYPE_BVEC2,   VAR_TYPE_BVEC3,   VAR_TYPE_BVEC4,   VAR_TYPE_IVEC2,   VAR_TYPE_IVEC3,
289         VAR_TYPE_IVEC4,   VAR_TYPE_UVEC2,   VAR_TYPE_UVEC3,   VAR_TYPE_UVEC4,   VAR_TYPE_MAT2,  VAR_TYPE_MAT3,
290         VAR_TYPE_MAT4,  VAR_TYPE_MAT2X2,  VAR_TYPE_MAT2X3,  VAR_TYPE_MAT2X4,  VAR_TYPE_MAT3X2,  VAR_TYPE_MAT3X3,
291         VAR_TYPE_MAT3X4,  VAR_TYPE_MAT4X2,  VAR_TYPE_MAT4X3,  VAR_TYPE_MAT4X4,  VAR_TYPE_DOUBLE,  VAR_TYPE_DMAT2,
292         VAR_TYPE_DMAT3,   VAR_TYPE_DMAT4,   VAR_TYPE_DMAT2X2, VAR_TYPE_DMAT2X3, VAR_TYPE_DMAT2X4, VAR_TYPE_DMAT3X2,
293         VAR_TYPE_DMAT3X3, VAR_TYPE_DMAT3X4, VAR_TYPE_DMAT4X2, VAR_TYPE_DMAT4X3, VAR_TYPE_DMAT4X4,
294 };
295
296 const test_var_type* Interface::GL::var_types   = var_types_gl;
297 const size_t             Interface::GL::n_var_types = sizeof(var_types_gl) / sizeof(var_types_gl[0]);
298
299 /** List of all supported opaque types. */
300 const glcts::test_var_type opaque_var_types[] = {
301         //Floating Point Sampler Types (opaque)
302         VAR_TYPE_SAMPLER2D, VAR_TYPE_SAMPLER3D, VAR_TYPE_SAMPLERCUBE, VAR_TYPE_SAMPLERCUBESHADOW, VAR_TYPE_SAMPLER2DSHADOW,
303         VAR_TYPE_SAMPLER2DARRAY, VAR_TYPE_SAMPLER2DARRAYSHADOW,
304         //Signed Integer Sampler Types (opaque)
305         VAR_TYPE_ISAMPLER2D, VAR_TYPE_ISAMPLER3D, VAR_TYPE_ISAMPLERCUBE, VAR_TYPE_ISAMPLER2DARRAY,
306         //Unsigned Integer Sampler Types (opaque)
307         VAR_TYPE_USAMPLER2D, VAR_TYPE_USAMPLER3D, VAR_TYPE_USAMPLERCUBE, VAR_TYPE_USAMPLER2DARRAY,
308 };
309
310 /** Sets up the type map that will be used to look up the type names, initialisation
311  *  values, etc., associated with each of the types used within the array tests
312  *
313  **/
314 template <class API>
315 void initializeMap()
316 {
317         int temp_index = 0;
318
319         // Set up the map
320         supported_variable_types_map[VAR_TYPE_BOOL]                                     = var_descriptors[temp_index++];
321         supported_variable_types_map[VAR_TYPE_INT]                                      = var_descriptors[temp_index++];
322         supported_variable_types_map[VAR_TYPE_UINT]                                     = var_descriptors[temp_index++];
323         supported_variable_types_map[VAR_TYPE_FLOAT]                            = var_descriptors[temp_index++];
324         supported_variable_types_map[VAR_TYPE_VEC2]                                     = var_descriptors[temp_index++];
325         supported_variable_types_map[VAR_TYPE_VEC3]                                     = var_descriptors[temp_index++];
326         supported_variable_types_map[VAR_TYPE_VEC4]                                     = var_descriptors[temp_index++];
327         supported_variable_types_map[VAR_TYPE_BVEC2]                            = var_descriptors[temp_index++];
328         supported_variable_types_map[VAR_TYPE_BVEC3]                            = var_descriptors[temp_index++];
329         supported_variable_types_map[VAR_TYPE_BVEC4]                            = var_descriptors[temp_index++];
330         supported_variable_types_map[VAR_TYPE_IVEC2]                            = var_descriptors[temp_index++];
331         supported_variable_types_map[VAR_TYPE_IVEC3]                            = var_descriptors[temp_index++];
332         supported_variable_types_map[VAR_TYPE_IVEC4]                            = var_descriptors[temp_index++];
333         supported_variable_types_map[VAR_TYPE_UVEC2]                            = var_descriptors[temp_index++];
334         supported_variable_types_map[VAR_TYPE_UVEC3]                            = var_descriptors[temp_index++];
335         supported_variable_types_map[VAR_TYPE_UVEC4]                            = var_descriptors[temp_index++];
336         supported_variable_types_map[VAR_TYPE_MAT2]                                     = var_descriptors[temp_index++];
337         supported_variable_types_map[VAR_TYPE_MAT3]                                     = var_descriptors[temp_index++];
338         supported_variable_types_map[VAR_TYPE_MAT4]                                     = var_descriptors[temp_index++];
339         supported_variable_types_map[VAR_TYPE_MAT2X2]                           = var_descriptors[temp_index++];
340         supported_variable_types_map[VAR_TYPE_MAT2X3]                           = var_descriptors[temp_index++];
341         supported_variable_types_map[VAR_TYPE_MAT2X4]                           = var_descriptors[temp_index++];
342         supported_variable_types_map[VAR_TYPE_MAT3X2]                           = var_descriptors[temp_index++];
343         supported_variable_types_map[VAR_TYPE_MAT3X3]                           = var_descriptors[temp_index++];
344         supported_variable_types_map[VAR_TYPE_MAT3X4]                           = var_descriptors[temp_index++];
345         supported_variable_types_map[VAR_TYPE_MAT4X2]                           = var_descriptors[temp_index++];
346         supported_variable_types_map[VAR_TYPE_MAT4X3]                           = var_descriptors[temp_index++];
347         supported_variable_types_map[VAR_TYPE_MAT4X4]                           = var_descriptors[temp_index++];
348         supported_variable_types_map[VAR_TYPE_IMAGEBUFFER]                      = var_descriptors[temp_index++];
349         supported_variable_types_map[VAR_TYPE_IIMAGEBUFFER]                     = var_descriptors[temp_index++];
350         supported_variable_types_map[VAR_TYPE_UIMAGEBUFFER]                     = var_descriptors[temp_index++];
351         supported_variable_types_map[VAR_TYPE_SAMPLERBUFFER]            = var_descriptors[temp_index++];
352         supported_variable_types_map[VAR_TYPE_ISAMPLERBUFFER]           = var_descriptors[temp_index++];
353         supported_variable_types_map[VAR_TYPE_USAMPLERBUFFER]           = var_descriptors[temp_index++];
354         supported_variable_types_map[VAR_TYPE_SAMPLER2D]                        = var_descriptors[temp_index++];
355         supported_variable_types_map[VAR_TYPE_SAMPLER3D]                        = var_descriptors[temp_index++];
356         supported_variable_types_map[VAR_TYPE_SAMPLERCUBE]                      = var_descriptors[temp_index++];
357         supported_variable_types_map[VAR_TYPE_SAMPLERCUBESHADOW]        = var_descriptors[temp_index++];
358         supported_variable_types_map[VAR_TYPE_SAMPLER2DSHADOW]          = var_descriptors[temp_index++];
359         supported_variable_types_map[VAR_TYPE_SAMPLER2DARRAY]           = var_descriptors[temp_index++];
360         supported_variable_types_map[VAR_TYPE_SAMPLER2DARRAYSHADOW] = var_descriptors[temp_index++];
361         supported_variable_types_map[VAR_TYPE_ISAMPLER2D]                       = var_descriptors[temp_index++];
362         supported_variable_types_map[VAR_TYPE_ISAMPLER3D]                       = var_descriptors[temp_index++];
363         supported_variable_types_map[VAR_TYPE_ISAMPLERCUBE]                     = var_descriptors[temp_index++];
364         supported_variable_types_map[VAR_TYPE_ISAMPLER2DARRAY]          = var_descriptors[temp_index++];
365         supported_variable_types_map[VAR_TYPE_USAMPLER2D]                       = var_descriptors[temp_index++];
366         supported_variable_types_map[VAR_TYPE_USAMPLER3D]                       = var_descriptors[temp_index++];
367         supported_variable_types_map[VAR_TYPE_USAMPLERCUBE]                     = var_descriptors[temp_index++];
368         supported_variable_types_map[VAR_TYPE_USAMPLER2DARRAY]          = var_descriptors[temp_index++];
369
370         if (API::USE_DOUBLE)
371         {
372                 temp_index = 0;
373
374                 supported_variable_types_map[VAR_TYPE_DOUBLE]  = var_double_descriptors[temp_index++];
375                 supported_variable_types_map[VAR_TYPE_DMAT2]   = var_double_descriptors[temp_index++];
376                 supported_variable_types_map[VAR_TYPE_DMAT3]   = var_double_descriptors[temp_index++];
377                 supported_variable_types_map[VAR_TYPE_DMAT4]   = var_double_descriptors[temp_index++];
378                 supported_variable_types_map[VAR_TYPE_DMAT2X2] = var_double_descriptors[temp_index++];
379                 supported_variable_types_map[VAR_TYPE_DMAT2X3] = var_double_descriptors[temp_index++];
380                 supported_variable_types_map[VAR_TYPE_DMAT2X4] = var_double_descriptors[temp_index++];
381                 supported_variable_types_map[VAR_TYPE_DMAT3X2] = var_double_descriptors[temp_index++];
382                 supported_variable_types_map[VAR_TYPE_DMAT3X3] = var_double_descriptors[temp_index++];
383                 supported_variable_types_map[VAR_TYPE_DMAT3X4] = var_double_descriptors[temp_index++];
384                 supported_variable_types_map[VAR_TYPE_DMAT4X2] = var_double_descriptors[temp_index++];
385                 supported_variable_types_map[VAR_TYPE_DMAT4X3] = var_double_descriptors[temp_index++];
386                 supported_variable_types_map[VAR_TYPE_DMAT4X4] = var_double_descriptors[temp_index++];
387         }
388 }
389
390 /** Macro appends default ending of main function to source string
391  *
392  * @param SOURCE Tested shader source
393  **/
394 #define DEFAULT_MAIN_ENDING(TYPE, SOURCE)                           \
395         {                                                               \
396                 /* Apply stage specific stuff */                            \
397                 switch (TYPE)                                               \
398                 {                                                           \
399                 case TestCaseBase<API>::VERTEX_SHADER_TYPE:                 \
400                         SOURCE += "\n   gl_Position = vec4(0.0);\n";            \
401                         break;                                                  \
402                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:               \
403                         break;                                                  \
404                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:                \
405                         break;                                                  \
406                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:               \
407                         SOURCE += emit_quad;                                    \
408                         break;                                                  \
409                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:    \
410                         SOURCE += set_tesseation;                               \
411                         break;                                                  \
412                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: \
413                         break;                                                  \
414                 default:                                                    \
415                         TCU_FAIL("Unrecognized shader type.");                  \
416                         break;                                                  \
417                 }                                                           \
418                                                                     \
419                 /* End main function */                                     \
420                 SOURCE += shader_end;                                       \
421         }
422
423 /** Macro executes positive test selected on USE_ALL_SHADER_STAGES
424  *
425  * @param TYPE  Tested shader stage
426  * @param SOURCE Tested shader source
427  * @param DELETE Selects if program should be deleted afterwards
428  **/
429 #define EXECUTE_POSITIVE_TEST(TYPE, SOURCE, DELETE, GPU5)                              \
430         {                                                                                  \
431                 const std::string* cs  = &empty_string;                                        \
432                 const std::string* vs  = &default_vertex_shader_source;                        \
433                 const std::string* tcs = &default_tc_shader_source;                            \
434                 const std::string* tes = &default_te_shader_source;                            \
435                 const std::string* gs  = &default_geometry_shader_source;                      \
436                 const std::string* fs  = &default_fragment_shader_source;                      \
437                                                                                        \
438                 switch (TYPE)                                                                  \
439                 {                                                                              \
440                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:                                   \
441                         cs  = &SOURCE;                                                             \
442                         vs  = &empty_string;                                                       \
443                         tcs = &empty_string;                                                       \
444                         tes = &empty_string;                                                       \
445                         gs  = &empty_string;                                                       \
446                         fs  = &empty_string;                                                       \
447                         break;                                                                     \
448                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:                                  \
449                         fs = &SOURCE;                                                              \
450                         break;                                                                     \
451                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:                                  \
452                         gs = &SOURCE;                                                              \
453                         break;                                                                     \
454                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:                       \
455                         tcs = &SOURCE;                                                             \
456                         break;                                                                     \
457                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:                    \
458                         tes = &SOURCE;                                                             \
459                         break;                                                                     \
460                 case TestCaseBase<API>::VERTEX_SHADER_TYPE:                                    \
461                         vs = &SOURCE;                                                              \
462                         break;                                                                     \
463                 default:                                                                       \
464                         TCU_FAIL("Invalid enum");                                                  \
465                         break;                                                                     \
466                 };                                                                             \
467                                                                                        \
468                 if (API::USE_ALL_SHADER_STAGES)                                                \
469                 {                                                                              \
470                         this->execute_positive_test(*vs, *tcs, *tes, *gs, *fs, *cs, DELETE, GPU5); \
471                 }                                                                              \
472                 else                                                                           \
473                 {                                                                              \
474                         this->execute_positive_test(*vs, *fs, DELETE, GPU5);                       \
475                 }                                                                              \
476         }
477
478 /** Macro executes either positive or negative test
479  *
480  * @param S             Selects negative test when 0, positive test otherwise
481  * @param TYPE  Tested shader stage
482  * @param SOURCE Tested shader source
483  **/
484 #define EXECUTE_SHADER_TEST(S, TYPE, SOURCE)              \
485         if (S)                                                \
486         {                                                     \
487                 EXECUTE_POSITIVE_TEST(TYPE, SOURCE, true, false); \
488         }                                                     \
489         else                                                  \
490         {                                                     \
491                 this->execute_negative_test(TYPE, SOURCE);        \
492         }
493
494 /** Test case constructor.
495  *
496  * @tparam API        Tested API descriptor
497  *
498  * @param context     EGL context ID.
499  * @param name        Name of a test case.
500  * @param description Test case description.
501  **/
502 template <class API>
503 TestCaseBase<API>::TestCaseBase(Context& context, const char* name, const char* description)
504         : tcu::TestCase(context.getTestContext(), name, description)
505         , context_id(context)
506         , program_object_id(0)
507         , compute_shader_object_id(0)
508         , fragment_shader_object_id(0)
509         , geometry_shader_object_id(0)
510         , tess_ctrl_shader_object_id(0)
511         , tess_eval_shader_object_id(0)
512         , vertex_shader_object_id(0)
513 {
514         /* Left blank on purpose */
515 }
516
517 /** Clears up the shaders and program that were created during the tests
518  *
519  * @tparam API Tested API descriptor
520  */
521 template <class API>
522 void TestCaseBase<API>::delete_objects(void)
523 {
524         const glw::Functions& gl = context_id.getRenderContext().getFunctions();
525
526         /* Release all ES objects that may have been created by iterate() */
527         if (program_object_id != 0)
528         {
529                 gl.deleteProgram(program_object_id);
530                 program_object_id = 0;
531         }
532
533         /* Use default program object to be sure the objects were released. */
534         gl.useProgram(0);
535 }
536
537 /** Releases all OpenGL ES objects that were created for test case purposes.
538  *
539  * @tparam API Tested API descriptor
540  */
541 template <class API>
542 void TestCaseBase<API>::deinit(void)
543 {
544         this->delete_objects();
545 }
546
547 /** Runs the actual test for each shader type.
548  *
549  * @tparam API               Tested API descriptor
550  *
551  *  @return QP_TEST_RESULT_FAIL - test has failed;
552  *          QP_TEST_RESULT_PASS - test has succeeded;
553  **/
554 template <class API>
555 tcu::TestNode::IterateResult TestCaseBase<API>::iterate(void)
556 {
557         test_shader_compilation(TestCaseBase<API>::VERTEX_SHADER_TYPE);
558         test_shader_compilation(TestCaseBase<API>::FRAGMENT_SHADER_TYPE);
559
560         if (API::USE_ALL_SHADER_STAGES)
561         {
562                 test_shader_compilation(TestCaseBase<API>::COMPUTE_SHADER_TYPE);
563                 test_shader_compilation(TestCaseBase<API>::GEOMETRY_SHADER_TYPE);
564                 test_shader_compilation(TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE);
565                 test_shader_compilation(TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE);
566         }
567
568         return STOP;
569 }
570
571 /** Generates a shader object of the specified type,
572  *  attaches the specified shader source,
573  *  compiles it, and returns the compilation result.
574  *
575  * @tparam API               Tested API descriptor
576  *
577  * @param shader_source      The source for the shader object.
578  * @param tested_shader_type The type of shader being compiled (vertex or fragment).
579  *
580  * @return Compilation result (GL_TRUE if the shader compilation succeeded, GL_FALSE otherwise).
581  **/
582 template <class API>
583 glw::GLint TestCaseBase<API>::compile_shader_and_get_compilation_result(const std::string& tested_snippet,
584                                                                                                                                                 TestShaderType   tested_shader_type,
585                                                                                                                                                 bool                       require_gpu_shader5)
586 {
587         static const char* preamble_cs = "\n"
588                                                                          "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
589                                                                          "\n";
590
591         static const char* preamble_gs = "\n"
592                                                                          "layout(points)                           in;\n"
593                                                                          "layout(triangle_strip, max_vertices = 4) out;\n"
594                                                                          "\n";
595
596         static const char* preamble_tcs = "\n"
597                                                                           "layout(vertices = 1) out;\n"
598                                                                           "\n";
599
600         static const char* preamble_tes = "\n"
601                                                                           "layout(isolines, point_mode) in;\n"
602                                                                           "\n";
603
604         glw::GLint                        compile_status   = GL_TRUE;
605         const glw::Functions& gl                           = context_id.getRenderContext().getFunctions();
606         glw::GLint                        shader_object_id = 0;
607
608         std::string shader_source;
609
610         if (true == tested_snippet.empty())
611         {
612                 return compile_status;
613         }
614
615         if (require_gpu_shader5)
616         {
617                 // Add the version number here, rather than in each individual test
618                 shader_source = API::shader_version_gpu5;
619         }
620         else
621         {
622                 // Add the version number here, rather than in each individual test
623                 shader_source = API::shader_version;
624         }
625
626         /* Apply stage specific stuff */
627         switch (tested_shader_type)
628         {
629         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
630                 break;
631         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
632                 break;
633         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
634                 shader_source += preamble_cs;
635                 break;
636         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
637                 shader_source += preamble_gs;
638                 break;
639         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
640                 shader_source += preamble_tcs;
641                 break;
642         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
643                 shader_source += preamble_tes;
644                 break;
645         default:
646                 TCU_FAIL("Unrecognized shader type.");
647                 break;
648         }
649
650         shader_source += tested_snippet;
651
652         /* Prepare shader object */
653         switch (tested_shader_type)
654         {
655         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
656         {
657                 shader_object_id = gl.createShader(GL_VERTEX_SHADER);
658                 assert(0 == vertex_shader_object_id);
659                 vertex_shader_object_id = shader_object_id;
660
661                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a vertex shader.");
662
663                 break;
664         } /* case TestCaseBase<API>::VERTEX_SHADER_TYPE: */
665         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
666         {
667                 shader_object_id = gl.createShader(GL_FRAGMENT_SHADER);
668                 assert(0 == fragment_shader_object_id);
669                 fragment_shader_object_id = shader_object_id;
670
671                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a fragment shader.");
672
673                 break;
674         } /* case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: */
675         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
676         {
677                 shader_object_id = gl.createShader(GL_COMPUTE_SHADER);
678                 assert(0 == compute_shader_object_id);
679                 compute_shader_object_id = shader_object_id;
680
681                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a compute shader.");
682
683                 break;
684         } /* case TestCaseBase<API>::COMPUTE_SHADER_TYPE: */
685         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
686         {
687                 shader_object_id = gl.createShader(GL_GEOMETRY_SHADER);
688                 assert(0 == geometry_shader_object_id);
689                 geometry_shader_object_id = shader_object_id;
690
691                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a geometry shader.");
692
693                 break;
694         } /* case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: */
695         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
696         {
697                 shader_object_id = gl.createShader(GL_TESS_CONTROL_SHADER);
698                 assert(0 == tess_ctrl_shader_object_id);
699                 tess_ctrl_shader_object_id = shader_object_id;
700
701                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a tesselation control shader.");
702
703                 break;
704         } /* case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: */
705         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
706         {
707                 shader_object_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
708                 assert(0 == tess_eval_shader_object_id);
709                 tess_eval_shader_object_id = shader_object_id;
710
711                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a tesselation evaluation shader.");
712
713                 break;
714         } /* case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: */
715         default:
716         {
717                 TCU_FAIL("Unrecognized shader type.");
718
719                 break;
720         } /* default: */
721         } /* switch (tested_shader_type) */
722
723         /* Assign source code to the objects */
724         const char* code_ptr = shader_source.c_str();
725
726 #if IS_DEBUG_DUMP_ALL_SHADERS
727         context_id.getTestContext().getLog() << tcu::TestLog::Message << "Compiling: " << tcu::TestLog::EndMessage;
728         context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(code_ptr);
729 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
730
731         gl.shaderSource(shader_object_id, 1 /* count */, &code_ptr, NULL);
732         GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed");
733
734         /* Compile the shader */
735         gl.compileShader(shader_object_id);
736         GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed");
737
738         /* Get the compilation result. */
739         gl.getShaderiv(shader_object_id, GL_COMPILE_STATUS, &compile_status);
740         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed");
741
742 #if IS_DEBUG
743         if (GL_TRUE != compile_status)
744         {
745                 glw::GLint  length = 0;
746                 std::string message;
747
748                 /* Error log length */
749                 gl.getShaderiv(shader_object_id, GL_INFO_LOG_LENGTH, &length);
750                 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
751
752                 /* Prepare storage */
753                 message.resize(length, 0);
754
755                 /* Get error log */
756                 gl.getShaderInfoLog(shader_object_id, length, 0, &message[0]);
757                 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
758
759                 context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0]
760                                                                                          << tcu::TestLog::EndMessage;
761
762 #if IS_DEBUG_DUMP_ALL_SHADERS
763 #else  /* IS_DEBUG_DUMP_ALL_SHADERS */
764                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(code_ptr);
765 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
766         }
767 #endif /* IS_DEBUG */
768
769         return compile_status;
770 }
771
772 /** Runs the negative test.
773  *  The shader sources are considered as invalid,
774  *  and the compilation of a shader object with the specified
775  *  shader source is expected to fail.
776  *
777  * @tparam API               Tested API descriptor
778  *
779  * @param tested_shader_type The type of shader object (can be fragment or vertex).
780  * @param shader_source      The source for the shader object to be used for this test.
781  *
782  *  @return QP_TEST_RESULT_FAIL - test has failed;
783  *          QP_TEST_RESULT_PASS - test has succeeded;
784  **/
785 template <class API>
786 tcu::TestNode::IterateResult TestCaseBase<API>::execute_negative_test(
787         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& shader_source)
788 {
789         glw::GLint                        compile_status = GL_FALSE;
790         const char*                       error_message  = 0;
791         const glw::Functions& gl                         = context_id.getRenderContext().getFunctions();
792         bool                              test_result   = true;
793
794         /* Try to generate and compile the shader object. */
795         switch (tested_shader_type)
796         {
797         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
798                 error_message =
799                         "The fragment shader was expected to fail to compile, but the compilation process was successful.";
800                 break;
801
802         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
803                 error_message =
804                         "The vertex shader was expected to fail to compile, but the compilation process was successful.";
805
806                 break;
807
808         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
809                 error_message =
810                         "The compute shader was expected to fail to compile, but the compilation process was successful.";
811                 break;
812
813         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
814                 error_message =
815                         "The geometry shader was expected to fail to compile, but the compilation process was successful.";
816                 break;
817
818         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
819                 error_message = "The tesselation control shader was expected to fail to compile, but the compilation process "
820                                                 "was successful.";
821                 break;
822
823         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
824                 error_message = "The tesselation evaluation shader was expected to fail to compile, but the compilation "
825                                                 "process was successful.";
826                 break;
827
828         default:
829                 TCU_FAIL("Unrecognized shader type.");
830                 test_result = false;
831
832                 break;
833         } /* switch (shader_type) */
834
835         compile_status = compile_shader_and_get_compilation_result(shader_source, tested_shader_type);
836
837         if (compile_status == GL_TRUE)
838         {
839                 TCU_FAIL(error_message);
840
841                 test_result = false;
842         }
843
844         /* Deallocate any resources used. */
845         this->delete_objects();
846         if (0 != compute_shader_object_id)
847         {
848                 gl.deleteShader(compute_shader_object_id);
849                 compute_shader_object_id = 0;
850         }
851         if (0 != fragment_shader_object_id)
852         {
853                 gl.deleteShader(fragment_shader_object_id);
854                 fragment_shader_object_id = 0;
855         }
856         if (0 != geometry_shader_object_id)
857         {
858                 gl.deleteShader(geometry_shader_object_id);
859                 geometry_shader_object_id = 0;
860         }
861         if (0 != tess_ctrl_shader_object_id)
862         {
863                 gl.deleteShader(tess_ctrl_shader_object_id);
864                 tess_ctrl_shader_object_id = 0;
865         }
866         if (0 != tess_eval_shader_object_id)
867         {
868                 gl.deleteShader(tess_eval_shader_object_id);
869                 tess_eval_shader_object_id = 0;
870         }
871         if (0 != vertex_shader_object_id)
872         {
873                 gl.deleteShader(vertex_shader_object_id);
874                 vertex_shader_object_id = 0;
875         }
876
877         /* Return test pass if true. */
878         if (true == test_result)
879         {
880                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
881         }
882
883         return CONTINUE;
884 }
885
886 /** Runs the positive test.
887  *  The shader sources are considered as valid,
888  *  and the compilation and program linking are expected to succeed.
889  *
890  * @tparam API                     Tested API descriptor
891  *
892  * @param vertex_shader_source     The source for the vertex shader to be used for this test.
893  * @param fragment_shader_source   The source for the fragment shader to be used for this test.
894  * @param delete_generated_objects If true, the compiled shader objects will be deleted before returning.
895  *
896  *  @return QP_TEST_RESULT_FAIL - test has failed;
897  *          QP_TEST_RESULT_PASS - test has succeeded;
898  **/
899 template <class API>
900 tcu::TestNode::IterateResult TestCaseBase<API>::execute_positive_test(const std::string& vertex_shader_source,
901                                                                                                                                           const std::string& fragment_shader_source,
902                                                                                                                                           bool                           delete_generated_objects,
903                                                                                                                                           bool                           require_gpu_shader5)
904 {
905         glw::GLint                        compile_status = GL_TRUE;
906         const glw::Functions& gl                         = context_id.getRenderContext().getFunctions();
907         glw::GLint                        link_status   = GL_TRUE;
908         bool                              test_result   = true;
909
910         /* Compile, and check the compilation result for the fragment shader object. */
911         compile_status = compile_shader_and_get_compilation_result(
912                 fragment_shader_source, TestCaseBase<API>::FRAGMENT_SHADER_TYPE, require_gpu_shader5);
913
914         if (compile_status == GL_FALSE)
915         {
916                 TCU_FAIL("The fragment shader was expected to compile successfully, but failed to compile.");
917
918                 test_result = false;
919         }
920
921         /* Compile, and check the compilation result for the vertex shader object. */
922         compile_status = compile_shader_and_get_compilation_result(
923                 vertex_shader_source, TestCaseBase<API>::VERTEX_SHADER_TYPE, require_gpu_shader5);
924
925         if (compile_status == GL_FALSE)
926         {
927                 TCU_FAIL("The vertex shader was expected to compile successfully, but failed to compile.");
928
929                 test_result = false;
930         }
931
932         if (true == test_result)
933         {
934                 /* Create program object. */
935                 assert(0 == program_object_id);
936                 program_object_id = gl.createProgram();
937                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a program object.");
938
939                 /* Configure the program object */
940                 gl.attachShader(program_object_id, fragment_shader_object_id);
941                 gl.attachShader(program_object_id, vertex_shader_object_id);
942                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed.");
943
944                 gl.deleteShader(fragment_shader_object_id);
945                 gl.deleteShader(vertex_shader_object_id);
946                 fragment_shader_object_id = 0;
947                 vertex_shader_object_id   = 0;
948
949                 /* Link the program object */
950                 gl.linkProgram(program_object_id);
951                 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed.");
952
953                 /* Make sure the linking operation succeeded. */
954                 gl.getProgramiv(program_object_id, GL_LINK_STATUS, &link_status);
955                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed.");
956
957                 if (link_status != GL_TRUE)
958                 {
959 #if IS_DEBUG
960                         glw::GLint  length = 0;
961                         std::string message;
962
963                         /* Get error log length */
964                         gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &length);
965                         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
966
967                         message.resize(length, 0);
968
969                         /* Get error log */
970                         gl.getProgramInfoLog(program_object_id, length, 0, &message[0]);
971                         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
972
973                         context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0]
974                                                                                                  << tcu::TestLog::EndMessage;
975
976 #if IS_DEBUG_DUMP_ALL_SHADERS
977 #else  /* IS_DEBUG_DUMP_ALL_SHADERS */
978                         context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(vertex_shader_source);
979                         context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(fragment_shader_source);
980 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
981 #endif /* IS_DEBUG */
982
983                         TCU_FAIL("Linking was expected to succeed, but the process was unsuccessful.");
984
985                         test_result = false;
986                 }
987         }
988
989         if (delete_generated_objects)
990         {
991                 /* Deallocate any resources used. */
992                 this->delete_objects();
993         }
994
995         /* Return test pass if true. */
996         if (true == test_result)
997         {
998                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
999         }
1000
1001         return CONTINUE;
1002 }
1003
1004 /** Runs the positive test.
1005  *  The shader sources are considered as valid,
1006  *  and the compilation and program linking are expected to succeed.
1007  *
1008  * @tparam API                     Tested API descriptor
1009  *
1010  * @param vertex_shader_source     The source for the vertex shader to be used for this test.
1011  * @param tess_ctrl_shader_source  The source for the vertex shader to be used for this test.
1012  * @param tess_eval_shader_source  The source for the vertex shader to be used for this test.
1013  * @param geometry_shader_source   The source for the vertex shader to be used for this test.
1014  * @param fragment_shader_source   The source for the vertex shader to be used for this test.
1015  * @param compute_shader_source    The source for the fragment shader to be used for this test.
1016  * @param delete_generated_objects If true, the compiled shader objects will be deleted before returning.
1017  *
1018  *  @return QP_TEST_RESULT_FAIL - test has failed;
1019  *          QP_TEST_RESULT_PASS - test has succeeded;
1020  **/
1021 template <class API>
1022 tcu::TestNode::IterateResult TestCaseBase<API>::execute_positive_test(
1023         const std::string& vertex_shader_source, const std::string& tess_ctrl_shader_source,
1024         const std::string& tess_eval_shader_source, const std::string& geometry_shader_source,
1025         const std::string& fragment_shader_source, const std::string& compute_shader_source, bool delete_generated_objects,
1026         bool require_gpu_shader5)
1027 {
1028         glw::GLint                        compile_status = GL_TRUE;
1029         const glw::Functions& gl                         = context_id.getRenderContext().getFunctions();
1030         glw::GLint                        link_status   = GL_TRUE;
1031         bool                              test_compute   = !compute_shader_source.empty();
1032         bool                              test_result   = true;
1033
1034         if (false == test_compute)
1035         {
1036                 /* Compile, and check the compilation result for the fragment shader object. */
1037                 compile_status = compile_shader_and_get_compilation_result(
1038                         fragment_shader_source, TestCaseBase<API>::FRAGMENT_SHADER_TYPE, require_gpu_shader5);
1039
1040                 if (compile_status == GL_FALSE)
1041                 {
1042                         TCU_FAIL("The fragment shader was expected to compile successfully, but failed to compile.");
1043
1044                         test_result = false;
1045                 }
1046
1047                 /* Compile, and check the compilation result for the geometry shader object. */
1048                 compile_status = compile_shader_and_get_compilation_result(
1049                         geometry_shader_source, TestCaseBase<API>::GEOMETRY_SHADER_TYPE, require_gpu_shader5);
1050
1051                 if (compile_status == GL_FALSE)
1052                 {
1053                         TCU_FAIL("The geometry shader was expected to compile successfully, but failed to compile.");
1054
1055                         test_result = false;
1056                 }
1057
1058                 /* Compile, and check the compilation result for the te shader object. */
1059                 compile_status = compile_shader_and_get_compilation_result(
1060                         tess_eval_shader_source, TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE, require_gpu_shader5);
1061
1062                 if (compile_status == GL_FALSE)
1063                 {
1064                         TCU_FAIL("The tesselation evaluation shader was expected to compile successfully, but failed to compile.");
1065
1066                         test_result = false;
1067                 }
1068
1069                 /* Compile, and check the compilation result for the tc shader object. */
1070                 compile_status = compile_shader_and_get_compilation_result(
1071                         tess_ctrl_shader_source, TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE, require_gpu_shader5);
1072
1073                 if (compile_status == GL_FALSE)
1074                 {
1075                         TCU_FAIL("The tesselation control shader was expected to compile successfully, but failed to compile.");
1076
1077                         test_result = false;
1078                 }
1079
1080                 /* Compile, and check the compilation result for the vertex shader object. */
1081                 compile_status = compile_shader_and_get_compilation_result(
1082                         vertex_shader_source, TestCaseBase<API>::VERTEX_SHADER_TYPE, require_gpu_shader5);
1083
1084                 if (compile_status == GL_FALSE)
1085                 {
1086                         TCU_FAIL("The vertex shader was expected to compile successfully, but failed to compile.");
1087
1088                         test_result = false;
1089                 }
1090         }
1091         else
1092         {
1093                 /* Compile, and check the compilation result for the compute shader object. */
1094                 compile_status = compile_shader_and_get_compilation_result(
1095                         compute_shader_source, TestCaseBase<API>::COMPUTE_SHADER_TYPE, require_gpu_shader5);
1096
1097                 if (compile_status == GL_FALSE)
1098                 {
1099                         TCU_FAIL("The compute shader was expected to compile successfully, but failed to compile.");
1100
1101                         test_result = false;
1102                 }
1103         }
1104
1105         if (true == test_result)
1106         {
1107                 /* Create program object. */
1108                 program_object_id = gl.createProgram();
1109                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a program object.");
1110
1111                 /* Configure the program object */
1112                 if (false == test_compute)
1113                 {
1114                         gl.attachShader(program_object_id, fragment_shader_object_id);
1115
1116                         if (geometry_shader_object_id)
1117                         {
1118                                 gl.attachShader(program_object_id, geometry_shader_object_id);
1119                         }
1120
1121                         if (tess_ctrl_shader_object_id)
1122                         {
1123                                 gl.attachShader(program_object_id, tess_ctrl_shader_object_id);
1124                         }
1125
1126                         if (tess_eval_shader_object_id)
1127                         {
1128                                 gl.attachShader(program_object_id, tess_eval_shader_object_id);
1129                         }
1130
1131                         gl.attachShader(program_object_id, vertex_shader_object_id);
1132                 }
1133                 else
1134                 {
1135                         gl.attachShader(program_object_id, compute_shader_object_id);
1136                 }
1137                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed.");
1138
1139                 if (false == test_compute)
1140                 {
1141                         gl.deleteShader(fragment_shader_object_id);
1142
1143                         if (geometry_shader_object_id)
1144                         {
1145                                 gl.deleteShader(geometry_shader_object_id);
1146                         }
1147
1148                         if (tess_ctrl_shader_object_id)
1149                         {
1150                                 gl.deleteShader(tess_ctrl_shader_object_id);
1151                         }
1152
1153                         if (tess_eval_shader_object_id)
1154                         {
1155                                 gl.deleteShader(tess_eval_shader_object_id);
1156                         }
1157
1158                         gl.deleteShader(vertex_shader_object_id);
1159                 }
1160                 else
1161                 {
1162                         gl.deleteShader(compute_shader_object_id);
1163                 }
1164
1165                 fragment_shader_object_id  = 0;
1166                 vertex_shader_object_id = 0;
1167                 geometry_shader_object_id  = 0;
1168                 tess_ctrl_shader_object_id = 0;
1169                 tess_eval_shader_object_id = 0;
1170                 compute_shader_object_id   = 0;
1171
1172                 /* Link the program object */
1173                 gl.linkProgram(program_object_id);
1174                 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed.");
1175
1176                 /* Make sure the linking operation succeeded. */
1177                 gl.getProgramiv(program_object_id, GL_LINK_STATUS, &link_status);
1178                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed.");
1179
1180                 if (link_status != GL_TRUE)
1181                 {
1182 #if IS_DEBUG
1183                         glw::GLint  length = 0;
1184                         std::string message;
1185
1186                         /* Get error log length */
1187                         gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &length);
1188                         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
1189
1190                         message.resize(length, 0);
1191
1192                         /* Get error log */
1193                         gl.getProgramInfoLog(program_object_id, length, 0, &message[0]);
1194                         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
1195
1196                         context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0]
1197                                                                                                  << tcu::TestLog::EndMessage;
1198
1199 #if IS_DEBUG_DUMP_ALL_SHADERS
1200                         if (false == test_compute)
1201                         {
1202                                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(vertex_shader_source);
1203                                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(tess_ctrl_shader_source);
1204                                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(tess_eval_shader_source);
1205                                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(geometry_shader_source);
1206                                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(fragment_shader_source);
1207                         }
1208                         else
1209                         {
1210                                 context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(compute_shader_source);
1211                         }
1212 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
1213 #endif /* IS_DEBUG */
1214
1215                         TCU_FAIL("Linking was expected to succeed, but the process was unsuccessful.");
1216
1217                         test_result = false;
1218                 }
1219         }
1220
1221         if (delete_generated_objects)
1222         {
1223                 /* Deallocate any resources used. */
1224                 this->delete_objects();
1225         }
1226
1227         /* Return test pass if true. */
1228         if (true == test_result)
1229         {
1230                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1231         }
1232
1233         return CONTINUE;
1234 }
1235
1236 /** Adds the specified @param sub_script onto the base_string @param number_of_elements times.
1237  *  E.g. extend_string("a", [2], 3) would give a[2][2][2].
1238  *
1239  * @tparam API               Tested API descriptor
1240  *
1241  * @param base_string        The base string that is to be added to.
1242  * @param sub_string         The string to be repeatedly added
1243  * @param number_of_elements The number of repetitions.
1244  *
1245  *  @return The extended string.
1246  **/
1247 template <class API>
1248 std::string TestCaseBase<API>::extend_string(std::string base_string, std::string sub_string, size_t number_of_elements)
1249 {
1250         std::string temp_string = base_string;
1251
1252         for (size_t sub_script_index = 0; sub_script_index < number_of_elements; sub_script_index++)
1253         {
1254                 temp_string += sub_string;
1255         }
1256
1257         return temp_string;
1258 }
1259
1260 /* Generates the shader source code for the SizedDeclarationsPrimitive
1261  * array tests, and attempts to compile each test shader, for both
1262  * vertex and fragment shaders.
1263  *
1264  * @tparam API               Tested API descriptor
1265  *
1266  * @param tested_shader_type The type of shader that is being tested
1267  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1268  *
1269  **/
1270 template <class API>
1271 void SizedDeclarationsPrimitive<API>::test_shader_compilation(
1272         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1273 {
1274         for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
1275         {
1276                 _supported_variable_types_map_const_iterator var_iterator =
1277                         supported_variable_types_map.find(API::var_types[var_type_index]);
1278
1279                 if (var_iterator != supported_variable_types_map.end())
1280                 {
1281                         /* Loop round for each var_types ("int", "uint", "float", etc.)
1282                          * We are testing a[][] to a [][][][][][][][], so start counter at 2. */
1283                         for (size_t max_dimension_limit = 2; max_dimension_limit <= API::MAX_ARRAY_DIMENSIONS;
1284                                  max_dimension_limit++)
1285                         {
1286                                 // Record the base varTypeModifier + varType
1287                                 std::string base_var_type                = var_iterator->second.type;
1288                                 std::string base_variable_string = base_var_type;
1289
1290                                 for (size_t base_sub_script_index = 0; base_sub_script_index <= max_dimension_limit;
1291                                          base_sub_script_index++)
1292                                 {
1293                                         std::string shader_source = "";
1294
1295                                         // Add the shader body start, and the base varTypeModifier + varType + variable name.
1296                                         shader_source += shader_start + "    " + base_variable_string + " a";
1297
1298                                         for (size_t remaining_sub_script_index = base_sub_script_index;
1299                                                  remaining_sub_script_index < max_dimension_limit; remaining_sub_script_index++)
1300                                         {
1301                                                 /* Add as many array sub_scripts as we can, up to the current dimension limit. */
1302                                                 shader_source += "[2]";
1303                                         }
1304
1305                                         /* End line */
1306                                         shader_source += ";\n";
1307
1308                                         /* End main */
1309                                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1310
1311                                         /* Execute test */
1312                                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1313
1314                                         /* From now on, we'll have an extra sub_script each time. */
1315                                         base_variable_string += "[2]";
1316                                 } /* for (int base_sub_script_index = 0; ...) */
1317                         }        /* for (int max_dimension_limit = 2; ...) */
1318                 }                 /* if var_type iterator found */
1319                 else
1320                 {
1321                         TCU_FAIL("Type not found.");
1322                 }
1323         } /* for (int var_type_index = 0; ...) */
1324 }
1325
1326 /* Generates the shader source code for the SizedDeclarationsStructTypes1
1327  * array tests, and attempts to compile each test shader, for both
1328  * vertex and fragment shaders.
1329  *
1330  * @tparam API               Tested API descriptor
1331  *
1332  * @param tested_shader_type The type of shader that is being tested
1333  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1334  */
1335 template <class API>
1336 void SizedDeclarationsStructTypes1<API>::test_shader_compilation(
1337         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1338 {
1339         std::string example_struct("struct light {\n"
1340                                                            "    float intensity;\n"
1341                                                            "    int   position;\n"
1342                                                            "};\n\n");
1343         std::string shader_source;
1344
1345         for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1346         {
1347                 shader_source = example_struct;
1348                 shader_source += shader_start;
1349                 shader_source += "    light[2]";
1350
1351                 for (size_t temp_dimension_index = 0; temp_dimension_index < max_dimension_index; temp_dimension_index++)
1352                 {
1353                         shader_source += "[2]";
1354                 }
1355
1356                 shader_source += " x;\n";
1357
1358                 /* End main */
1359                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1360
1361                 /* Execute test */
1362                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1363
1364         } /* for (int max_dimension_index = 1; ...) */
1365 }
1366
1367 /* Generates the shader source code for the SizedDeclarationsStructTypes2
1368  * array tests, and attempts to compile each test shader, for both
1369  * vertex and fragment shaders.
1370  *
1371  * @tparam API               Tested API descriptor
1372  *
1373  * @param tested_shader_type The type of shader that is being tested
1374  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1375  */
1376 template <class API>
1377 void SizedDeclarationsStructTypes2<API>::test_shader_compilation(
1378         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1379 {
1380         std::string structure_declaration = "struct MyStructure {\n"
1381                                                                                 "   float a[2], "
1382                                                                                 "b[2][2], "
1383                                                                                 "c[2][2][2], "
1384                                                                                 "d[2][2][2][2], "
1385                                                                                 "e[2][2][2][2][2], "
1386                                                                                 "f[2][2][2][2][2][2], "
1387                                                                                 "g[2][2][2][2][2][2][2], "
1388                                                                                 "h[2][2][2][2][2][2][2][2];\n"
1389                                                                                 "} myStructureObject;\n\n";
1390         std::string shader_source = structure_declaration;
1391
1392         shader_source += shader_start;
1393
1394         /* End main */
1395         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1396
1397         /* Execute test */
1398         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1399 }
1400
1401 /* Generates the shader source code for the SizedDeclarationsStructTypes3
1402  * array tests, and attempts to compile each test shader, for both
1403  * vertex and fragment shaders.
1404  *
1405  * @tparam API               Tested API descriptor
1406  *
1407  * @param tested_shader_type The type of shader that is being tested
1408  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1409  */
1410 template <class API>
1411 void SizedDeclarationsStructTypes3<API>::test_shader_compilation(
1412         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1413 {
1414         std::string example_struct("struct light {\n"
1415                                                            "    float[2] intensity;\n"
1416                                                            "    int[2] position;\n"
1417                                                            "};\n");
1418         std::string shader_source;
1419
1420         for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1421         {
1422                 shader_source = example_struct;
1423                 shader_source += shader_start;
1424                 shader_source += this->extend_string("    light my_light_object", "[2]", max_dimension_index);
1425                 shader_source += ";\n";
1426
1427                 /* End main */
1428                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1429
1430                 /* Execute test */
1431                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1432         } /* for (int max_dimension_index = 1; ...) */
1433 }
1434
1435 /* Generates the shader source code for the SizedDeclarationsStructTypes4
1436  * array tests, and attempts to compile each test shader, for both
1437  * vertex and fragment shaders.
1438  *
1439  * @tparam API               Tested API descriptor
1440  *
1441  * @param tested_shader_type The type of shader that is being tested
1442  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1443  */
1444 template <class API>
1445 void SizedDeclarationsStructTypes4<API>::test_shader_compilation(
1446         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1447 {
1448         std::string example_struct("struct light {\n"
1449                                                            "    float[2] intensity;\n"
1450                                                            "    int[2] position;\n"
1451                                                            "} lightVar[2]");
1452         std::string shader_source;
1453
1454         for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1455         {
1456                 shader_source = example_struct;
1457
1458                 for (size_t temp_dimension_index = 0; temp_dimension_index < max_dimension_index; temp_dimension_index++)
1459                 {
1460                         shader_source += "[2]";
1461                 }
1462                 shader_source += ";\n\n";
1463                 shader_source += shader_start;
1464
1465                 /* End main */
1466                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1467
1468                 /* Execute test */
1469                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1470         } /* for (int max_dimension_index = 1; ...) */
1471 }
1472
1473 /* Generates the shader source code for the SizedDeclarationsTypenameStyle1
1474  * array tests, and attempts to compile each test shader, for both
1475  * vertex and fragment shaders.
1476  *
1477  * @tparam API               Tested API descriptor
1478  *
1479  * @param tested_shader_type The type of shader that is being tested
1480  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1481  */
1482 template <class API>
1483 void SizedDeclarationsTypenameStyle1<API>::test_shader_compilation(
1484         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1485 {
1486         for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1487         {
1488                 std::string shader_source = shader_start;
1489
1490                 shader_source += this->extend_string("    float", "[2]", max_dimension_index);
1491                 shader_source += this->extend_string(" x", "[2]", API::MAX_ARRAY_DIMENSIONS - max_dimension_index);
1492                 shader_source += ";\n";
1493
1494                 /* End main */
1495                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1496
1497                 /* Execute test */
1498                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1499         } /* for (int max_dimension_index = 1; ...) */
1500 }
1501
1502 /* Generates the shader source code for the SizedDeclarationsTypenameStyle2
1503  * array tests, and attempts to compile each test shader, for both
1504  * vertex and fragment shaders.
1505  *
1506  * @tparam API               Tested API descriptor
1507  *
1508  * @param tested_shader_type The type of shader that is being tested
1509  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1510  */
1511 template <class API>
1512 void SizedDeclarationsTypenameStyle2<API>::test_shader_compilation(
1513         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1514 {
1515         std::string shader_source = shader_start;
1516
1517         shader_source += this->extend_string("    float", "[2]", 2);
1518         shader_source += this->extend_string(" a", "[2]", 0);
1519         shader_source += ", ";
1520         shader_source += this->extend_string("b", "[2]", 1);
1521         shader_source += ", ";
1522         shader_source += this->extend_string("c", "[2]", 2);
1523         shader_source += ", ";
1524         shader_source += this->extend_string("d", "[2]", 3);
1525         shader_source += ", ";
1526         shader_source += this->extend_string("e", "[2]", 4);
1527         shader_source += ", ";
1528         shader_source += this->extend_string("f", "[2]", 5);
1529         shader_source += ", ";
1530         shader_source += this->extend_string("g", "[2]", 6);
1531         shader_source += ";\n";
1532
1533         /* End main */
1534         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1535
1536         /* Execute test */
1537         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1538 }
1539
1540 /* Generates the shader source code for the SizedDeclarationsTypenameStyle3
1541  * array tests, and attempts to compile each test shader, for both
1542  * vertex and fragment shaders.
1543  *
1544  * @tparam API               Tested API descriptor
1545  *
1546  * @param tested_shader_type The type of shader that is being tested
1547  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1548  */
1549 template <class API>
1550 void SizedDeclarationsTypenameStyle3<API>::test_shader_compilation(
1551         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1552 {
1553         std::string shader_source = "struct{\n" + this->extend_string("    float", "[2]", 2);
1554
1555         shader_source += this->extend_string(" a", "[2]", API::MAX_ARRAY_DIMENSIONS - API::MAX_ARRAY_DIMENSIONS);
1556         shader_source += ",";
1557         shader_source += this->extend_string("    b", "[2]", 1);
1558         shader_source += ",";
1559         shader_source += this->extend_string("    c", "[2]", 2);
1560         shader_source += ",";
1561         shader_source += this->extend_string("    d", "[2]", 3);
1562         shader_source += ",";
1563         shader_source += this->extend_string("    e", "[2]", 4);
1564         shader_source += ",";
1565         shader_source += this->extend_string("    f", "[2]", 5);
1566         shader_source += ",";
1567         shader_source += this->extend_string("    g", "[2]", 6);
1568         shader_source += ";\n} x;\n\n";
1569         shader_source += shader_start;
1570
1571         /* End main */
1572         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1573
1574         /* Execute test */
1575         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1576 }
1577
1578 /* Generates the shader source code for the SizedDeclarationsTypenameStyle4
1579  * array tests, and attempts to compile each test shader, for both
1580  * vertex and fragment shaders.
1581  *
1582  * @tparam API               Tested API descriptor
1583  *
1584  * @param tested_shader_type The type of shader that is being tested
1585  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1586  */
1587 template <class API>
1588 void SizedDeclarationsTypenameStyle4<API>::test_shader_compilation(
1589         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1590 {
1591         std::string example_struct_begin("struct light {\n");
1592         std::string example_struct_end("};\n\n");
1593
1594         for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1595         {
1596                 std::string shader_source = example_struct_begin;
1597
1598                 shader_source += this->extend_string("    float", "[2]", max_dimension_index);
1599                 shader_source += this->extend_string(" x", "[2]", API::MAX_ARRAY_DIMENSIONS - max_dimension_index);
1600                 shader_source += ";\n";
1601                 shader_source += example_struct_end;
1602                 shader_source += shader_start;
1603
1604                 /* End main */
1605                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1606
1607                 /* Execute test */
1608                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1609         } /* for (int max_dimension_index = 1; ...) */
1610 }
1611
1612 /* Generates the shader source code for the SizedDeclarationsTypenameStyle5
1613  * array tests, and attempts to compile each test shader, for both
1614  * vertex and fragment shaders.
1615  *
1616  * @tparam API               Tested API descriptor
1617  *
1618  * @param tested_shader_type The type of shader that is being tested
1619  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1620  */
1621 template <class API>
1622 void SizedDeclarationsTypenameStyle5<API>::test_shader_compilation(
1623         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1624 {
1625         std::string example_struct_begin("struct light {\n");
1626         std::string example_struct_end("};\n\n");
1627
1628         std::string shader_source = example_struct_begin;
1629
1630         shader_source += this->extend_string("    float", "[2]", 2);
1631         shader_source += this->extend_string(" a", "[2]", API::MAX_ARRAY_DIMENSIONS - API::MAX_ARRAY_DIMENSIONS);
1632         shader_source += ", ";
1633         shader_source += this->extend_string("b", "[2]", 2);
1634         shader_source += ", ";
1635         shader_source += this->extend_string("c", "[2]", 3);
1636         shader_source += ", ";
1637         shader_source += this->extend_string("d", "[2]", 4);
1638         shader_source += ", ";
1639         shader_source += this->extend_string("e", "[2]", 5);
1640         shader_source += ", ";
1641         shader_source += this->extend_string("f", "[2]", 6);
1642         shader_source += ";\n";
1643         shader_source += example_struct_end;
1644         shader_source += shader_start;
1645
1646         /* End main */
1647         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1648
1649         /* Execute test */
1650         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1651 }
1652
1653 /* Generates the shader source code for the SizedDeclarationsFunctionParams
1654  * array tests, and attempts to compile each test shader, for both
1655  * vertex and fragment shaders.
1656  *
1657  * @tparam API               Tested API descriptor
1658  *
1659  * @param tested_shader_type The type of shader that is being tested
1660  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1661  */
1662 template <class API>
1663 void SizedDeclarationsFunctionParams<API>::test_shader_compilation(
1664         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1665 {
1666         size_t          dimension_index = 0;
1667         std::string example_struct1("\nvoid my_function(");
1668         std::string example_struct2(")\n"
1669                                                                 "{\n"
1670                                                                 "}\n\n");
1671         std::string base_variable_string;
1672         std::string variable_basenames[API::MAX_ARRAY_DIMENSIONS] = { "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8" };
1673         std::string full_variable_names[API::MAX_ARRAY_DIMENSIONS];
1674
1675         for (size_t max_dimension_index = 0; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1676         {
1677                 full_variable_names[max_dimension_index] =
1678                         this->extend_string(variable_basenames[max_dimension_index], "[2]", max_dimension_index + 1);
1679         }
1680
1681         for (size_t max_dimension_index = 0; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1682         {
1683                 base_variable_string += "float ";
1684                 base_variable_string += full_variable_names[max_dimension_index];
1685                 base_variable_string += ";\n";
1686         }
1687
1688         base_variable_string += example_struct1;
1689         base_variable_string += this->extend_string("float a", "[2]", 1);
1690         base_variable_string += ", ";
1691         base_variable_string += this->extend_string("float b", "[2]", 2);
1692         base_variable_string += ", ";
1693         base_variable_string += this->extend_string("float c", "[2]", 3);
1694         base_variable_string += ", ";
1695         base_variable_string += this->extend_string("float d", "[2]", 4);
1696         base_variable_string += ", ";
1697         base_variable_string += this->extend_string("float e", "[2]", 5);
1698         base_variable_string += ", ";
1699         base_variable_string += this->extend_string("float f", "[2]", 6);
1700         base_variable_string += ", ";
1701         base_variable_string += this->extend_string("float g", "[2]", 7);
1702         base_variable_string += ", ";
1703         base_variable_string += this->extend_string("float h", "[2]", 8);
1704         base_variable_string += example_struct2;
1705
1706         std::string shader_source = base_variable_string;
1707
1708         shader_source += shader_start;
1709         shader_source += "    my_function(";
1710
1711         for (dimension_index = 0; dimension_index < API::MAX_ARRAY_DIMENSIONS - 1; dimension_index++)
1712         {
1713                 shader_source += variable_basenames[dimension_index];
1714                 shader_source += ", ";
1715         }
1716
1717         shader_source += variable_basenames[dimension_index];
1718         shader_source += ");\n";
1719
1720         /* End main */
1721         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1722
1723         /* Execute test */
1724         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1725
1726         /* Only the previous case should succeed, so start from index 1 rather than 0.
1727          * The other cases should fail, so only compile them, rather than trying to also link them.
1728          * We'll swap items 2/3, then 2/4, then 2/5, then 2/6, ...
1729          * Then we'll swap items 3/4, then 3/5, ...
1730          * Repeat, starting for 4/5-8, 5/6-8, 6/7-8...
1731          * Finally, we'll swap items 7/8
1732          */
1733         for (size_t swap_item = 1; swap_item < API::MAX_ARRAY_DIMENSIONS; swap_item++)
1734         {
1735                 for (size_t max_dimension_index = swap_item + 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS;
1736                          max_dimension_index++)
1737                 {
1738                         std::string temp = variable_basenames[swap_item];
1739
1740                         shader_source                                                   = base_variable_string;
1741                         variable_basenames[swap_item]                   = variable_basenames[max_dimension_index];
1742                         variable_basenames[max_dimension_index] = temp;
1743
1744                         shader_source += shader_start;
1745                         shader_source += "    my_function(";
1746
1747                         for (dimension_index = 0; dimension_index < API::MAX_ARRAY_DIMENSIONS - 1; dimension_index++)
1748                         {
1749                                 shader_source += variable_basenames[dimension_index];
1750                                 shader_source += ", ";
1751                         }
1752
1753                         shader_source += variable_basenames[dimension_index];
1754                         shader_source += ");\n";
1755
1756                         temp                                                                    = variable_basenames[swap_item];
1757                         variable_basenames[swap_item]                   = variable_basenames[max_dimension_index];
1758                         variable_basenames[max_dimension_index] = temp;
1759
1760                         /* End main */
1761                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1762
1763                         /* Execute test */
1764                         this->execute_negative_test(tested_shader_type, shader_source);
1765                 } /* for (int max_dimension_index = swap_item + 1; ...) */
1766         }        /* for (int swap_item = 1; ...) */
1767 }
1768
1769 /* Generates the shader source code for the sized_declarations_invalid_sizes1
1770  * array tests, and attempts to compile each test shader, for both
1771  * vertex and fragment shaders.
1772  *
1773  * @tparam API               Tested API descriptor
1774  *
1775  * @param tested_shader_type The type of shader that is being tested
1776  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1777  */
1778 template <class API>
1779 void sized_declarations_invalid_sizes1<API>::test_shader_compilation(
1780         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1781 {
1782         std::string invalid_declarations[] = {
1783                 "float x[2][2][2][0];\n", "float x[2][2][0][2];\n", "float x[2][0][2][2];\n", "float x[0][2][2][2];\n",
1784                 "float x[2][2][0][0];\n", "float x[2][0][2][0];\n", "float x[0][2][2][0];\n", "float x[2][0][0][2];\n",
1785                 "float x[0][2][0][2];\n", "float x[0][0][2][2];\n", "float x[2][0][0][0];\n", "float x[0][2][0][0];\n",
1786                 "float x[0][0][2][0];\n", "float x[0][0][0][2];\n", "float x[0][0][0][0];\n"
1787         };
1788
1789         for (size_t invalid_declarations_index = 0;
1790                  invalid_declarations_index < sizeof(invalid_declarations) / sizeof(invalid_declarations);
1791                  invalid_declarations_index++)
1792         {
1793                 std::string shader_source;
1794
1795                 shader_source = shader_start;
1796                 shader_source += invalid_declarations[invalid_declarations_index];
1797
1798                 /* End main */
1799                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1800
1801                 /* Execute test */
1802                 this->execute_negative_test(tested_shader_type, shader_source);
1803         } /* for (int invalid_declarations_index = 0; ...) */
1804 }
1805
1806 /* Generates the shader source code for the sized_declarations_invalid_sizes2
1807  * array tests, and attempts to compile each test shader, for both
1808  * vertex and fragment shaders.
1809  *
1810  * @tparam API               Tested API descriptor
1811  *
1812  * @param tested_shader_type The type of shader that is being tested
1813  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1814  */
1815 template <class API>
1816 void sized_declarations_invalid_sizes2<API>::test_shader_compilation(
1817         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1818 {
1819         std::string invalid_declarations[] = {
1820                 "    float x[2][2][2][-1];\n",   "    float x[2][2][-1][2];\n",   "    float x[2][-1][2][2];\n",
1821                 "    float x[-1][2][2][2];\n",   "    float x[2][2][-1][-1];\n",  "    float x[2][-1][2][-1];\n",
1822                 "    float x[-1][2][2][-1];\n",  "    float x[2][-1][-1][2];\n",  "    float x[-1][2][-1][2];\n",
1823                 "    float x[-1][-1][2][2];\n",  "    float x[2][-1][-1][-1];\n", "    float x[-1][2][-1][-1];\n",
1824                 "    float x[-1][-1][2][-1];\n", "    float x[-1][-1][-1][2];\n", "    float x[-1][-1][-1][-1];\n"
1825         };
1826
1827         for (size_t invalid_declarations_index = 0;
1828                  invalid_declarations_index < sizeof(invalid_declarations) / sizeof(invalid_declarations);
1829                  invalid_declarations_index++)
1830         {
1831                 std::string shader_source;
1832
1833                 shader_source = shader_start;
1834                 shader_source += invalid_declarations[invalid_declarations_index];
1835
1836                 /* End main */
1837                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1838
1839                 /* Execute test */
1840                 this->execute_negative_test(tested_shader_type, shader_source);
1841         } /* for (int invalid_declarations_index = 0; ...) */
1842 }
1843
1844 /* Generates the shader source code for the sized_declarations_invalid_sizes3
1845  * array tests, and attempts to compile each test shader, for both
1846  * vertex and fragment shaders.
1847  *
1848  * @tparam API               Tested API descriptor
1849  *
1850  * @param tested_shader_type The type of shader that is being tested
1851  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1852  */
1853 template <class API>
1854 void sized_declarations_invalid_sizes3<API>::test_shader_compilation(
1855         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1856 {
1857         std::string invalid_declarations[] = {
1858                 "    float x[2][2][2][a];\n", "    float x[2][2][a][2];\n", "    float x[2][a][2][2];\n",
1859                 "    float x[a][2][2][2];\n", "    float x[2][2][a][a];\n", "    float x[2][a][2][a];\n",
1860                 "    float x[a][2][2][a];\n", "    float x[2][a][a][2];\n", "    float x[a][2][a][2];\n",
1861                 "    float x[a][a][2][2];\n", "    float x[2][a][a][a];\n", "    float x[a][2][a][a];\n",
1862                 "    float x[a][a][2][a];\n", "    float x[a][a][a][2];\n", "    float x[a][a][a][a];\n"
1863         };
1864         std::string non_constant_variable_declaration = "    uint a = 2u;\n";
1865
1866         for (size_t invalid_declarations_index = 0;
1867                  invalid_declarations_index < sizeof(invalid_declarations) / sizeof(invalid_declarations);
1868                  invalid_declarations_index++)
1869         {
1870                 std::string shader_source;
1871
1872                 shader_source = shader_start;
1873                 shader_source += non_constant_variable_declaration;
1874                 shader_source += invalid_declarations[invalid_declarations_index];
1875
1876                 /* End main */
1877                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1878
1879                 /* Execute test */
1880                 this->execute_negative_test(tested_shader_type, shader_source);
1881         } /* for (int invalid_declarations_index = 0; ...) */
1882 }
1883
1884 /* Generates the shader source code for the sized_declarations_invalid_sizes4
1885  * array tests, and attempts to compile each test shader, for both
1886  * vertex and fragment shaders.
1887  *
1888  * @tparam API               Tested API descriptor
1889  *
1890  * @param tested_shader_type The type of shader that is being tested
1891  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1892  */
1893 template <class API>
1894 void sized_declarations_invalid_sizes4<API>::test_shader_compilation(
1895         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1896 {
1897         std::string input[] = { "    float x[2,2][2][2];\n", "    float x[2][2,2][2];\n", "    float x[2][2][2,2];\n",
1898                                                         "    float x[2,2,2][2];\n",  "    float x[2][2,2,2];\n",  "    float x[2,2,2,2];\n" };
1899
1900         for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
1901         {
1902                 std::string shader_source;
1903
1904                 shader_source += shader_start;
1905                 shader_source += input[string_index];
1906
1907                 /* End main */
1908                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1909
1910                 /* Execute test */
1911                 this->execute_negative_test(tested_shader_type, shader_source);
1912         } /* for (int string_index = 0; ...) */
1913 }
1914
1915 /* Constructs a suitable constructor for the specified number of dimensions.
1916  *
1917  * @tparam API            Tested API descriptor
1918  *
1919  * @param var_type        The type of the variable
1920  * @param dimension_index The current recursion level (counts down)
1921  * @param init_string     The initialisation string
1922  */
1923 template <class API>
1924 std::string ConstructorsAndUnsizedDeclConstructors1<API>::recursively_initialise(std::string var_type,
1925                                                                                                                                                                  size_t          dimension_index,
1926                                                                                                                                                                  std::string init_string)
1927 {
1928         std::string temp_string;
1929
1930         if (dimension_index == 0)
1931         {
1932                 temp_string = init_string;
1933         }
1934         else
1935         {
1936                 std::string prefix = "\n";
1937
1938                 for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
1939                 {
1940                         prefix += "    ";
1941                 }
1942
1943                 prefix += this->extend_string(var_type, "[]", dimension_index);
1944                 prefix += "(";
1945                 for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
1946                 {
1947                         temp_string += prefix;
1948                         temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
1949                         prefix = ", ";
1950                         if (sub_script_index == 1)
1951                         {
1952                                 break;
1953                         }
1954                 }
1955                 temp_string += ")";
1956         }
1957
1958         return temp_string;
1959 }
1960
1961 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructors1
1962  * array tests, and attempts to compile each test shader, for both
1963  * vertex and fragment shaders.
1964  *
1965  * @tparam API               Tested API descriptor
1966  *
1967  * @param tested_shader_type The type of shader that is being tested
1968  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1969  */
1970 template <class API>
1971 void ConstructorsAndUnsizedDeclConstructors1<API>::test_shader_compilation(
1972         typename TestCaseBase<API>::TestShaderType tested_shader_type)
1973 {
1974         //vec4 color = vec4(0.0, 1.0, 0.0, 1.0);
1975         int num_var_types = API::n_var_types;
1976
1977         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
1978         {
1979                 _supported_variable_types_map_const_iterator var_iterator =
1980                         supported_variable_types_map.find(API::var_types[var_type_index]);
1981
1982                 if (var_iterator != supported_variable_types_map.end())
1983                 {
1984                         for (size_t max_dimension_index = 2; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1985                         {
1986                                 std::string base_variable_string =
1987                                         this->extend_string("    " + var_iterator->second.type + " a", "[]", max_dimension_index);
1988
1989                                 base_variable_string += " = ";
1990                                 base_variable_string += recursively_initialise(var_iterator->second.type, max_dimension_index,
1991                                                                                                                            var_iterator->second.initializer_with_ones);
1992                                 base_variable_string += ";\n\n";
1993
1994                                 std::string shader_source = shader_start + base_variable_string;
1995
1996                                 /* End main */
1997                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1998
1999                                 /* Execute test */
2000                                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2001                         } /* for (int max_dimension_index = 1; ...) */
2002                 }        /* if var_type iterator found */
2003                 else
2004                 {
2005                         TCU_FAIL("Type not found.");
2006                 }
2007         } /* for (int var_type_index = 0; ...) */
2008
2009         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2010         {
2011                 _supported_variable_types_map_const_iterator var_iterator =
2012                         supported_variable_types_map.find(API::var_types[var_type_index]);
2013
2014                 if (var_iterator != supported_variable_types_map.end())
2015                 {
2016                         std::string base_structure = "struct my_structure\n";
2017
2018                         base_structure += "{\n";
2019                         base_structure += "    " + var_iterator->second.type + " b;\n";
2020                         base_structure += "    " + var_iterator->second.type + " c;\n";
2021                         base_structure += "};\n\n";
2022
2023                         for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2024                         {
2025                                 std::string outer_separator = "(";
2026                                 std::string base_variable_string;
2027
2028                                 base_variable_string +=
2029                                         this->extend_string("    " + var_iterator->second.type + " a", "[2]", max_dimension_index);
2030                                 base_variable_string += " = ";
2031                                 base_variable_string += recursively_initialise(var_iterator->second.type, max_dimension_index,
2032                                                                                                                            var_iterator->second.initializer_with_ones);
2033                                 base_variable_string += ";\n\n";
2034
2035                                 std::string shader_source = base_structure + shader_start + base_variable_string;
2036
2037                                 /* End main */
2038                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2039
2040                                 /* Execute test */
2041                                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2042                         } /* for (int max_dimension_index = 1; ...) */
2043                 }        /* if var_type iterator found */
2044                 else
2045                 {
2046                         TCU_FAIL("Type not found.");
2047                 }
2048         } /* for (int var_type_index = 0; ...) */
2049 }
2050
2051 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructors2
2052  * array tests, and attempts to compile each test shader, for both
2053  * vertex and fragment shaders.
2054  *
2055  * @tparam API               Tested API descriptor
2056  *
2057  * @param tested_shader_type The type of shader that is being tested
2058  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2059  */
2060 template <class API>
2061 void ConstructorsAndUnsizedDeclConstructors2<API>::test_shader_compilation(
2062         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2063 {
2064         std::string base_variable_string = "    float[2][2] x = float[2][2](float[4](1.0, 2.0, 3.0, 4.0));\n";
2065         std::string shader_source                = shader_start + base_variable_string;
2066
2067         /* End main */
2068         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2069
2070         /* Execute test */
2071         this->execute_negative_test(tested_shader_type, shader_source);
2072
2073         base_variable_string = "float[2][2] x = float[2][2](float[1][4](float[4](1.0, 2.0, 3.0, 4.0)));\n\n";
2074         shader_source            = base_variable_string + shader_start;
2075
2076         /* End main */
2077         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2078
2079         /* Execute test */
2080         this->execute_negative_test(tested_shader_type, shader_source);
2081 }
2082
2083 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedConstructors
2084  * array tests, and attempts to compile each test shader, for both
2085  * vertex and fragment shaders.
2086  *
2087  * @tparam API               Tested API descriptor
2088  *
2089  * @param tested_shader_type The type of shader that is being tested
2090  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2091  */
2092 template <class API>
2093 void ConstructorsAndUnsizedDeclUnsizedConstructors<API>::test_shader_compilation(
2094         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2095 {
2096         std::string shader_variable_declarations = "= float[2][1][2][1](\n"
2097                                                                                            "        float[1][2][1](\n"
2098                                                                                            "            float[2][1]( \n"
2099                                                                                            "                float[1](12.3), float[1](54.2) \n"
2100                                                                                            "            )\n"
2101                                                                                            "        ),\n"
2102                                                                                            "        float[1][2][1](\n"
2103                                                                                            "            float[2][1]( \n"
2104                                                                                            "                float[1]( 3.2), float[1]( 7.4) \n"
2105                                                                                            "            )\n"
2106                                                                                            "        )\n"
2107                                                                                            "    );\n\n";
2108
2109         std::string input[] = { "float a[2][1][2][]", "float a[2][1][][1]", "float a[2][1][][]", "float a[2][][2][1]",
2110                                                         "float a[2][][2][]",  "float a[2][][][1]",  "float a[2][][][]",  "float a[][1][2][1]",
2111                                                         "float a[][1][2][]",  "float a[][1][][1]",  "float a[][1][][]",  "float a[][][2][1]",
2112                                                         "float a[][][2][]",   "float a[][][][1]",   "float a[][][][]" };
2113
2114         for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
2115         {
2116                 std::string shader_source = shader_start + "    " + input[string_index] + shader_variable_declarations;
2117
2118                 /* End main */
2119                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2120
2121                 /* Execute test */
2122                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2123         } /* for (int string_index = 0; ...) */
2124 }
2125
2126 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConst
2127  * array tests, and attempts to compile each test shader, for both
2128  * vertex and fragment shaders.
2129  *
2130  * @tparam API               Tested API descriptor
2131  *
2132  * @param tested_shader_type The type of shader that is being tested
2133  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2134  */
2135 template <class API>
2136 void ConstructorsAndUnsizedDeclConst<API>::test_shader_compilation(
2137         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2138 {
2139         std::string shader_source = "const float[2][2] x = float[2][2](float[2](1.0, 2.0), float[2](3.0, 4.0));\n\n";
2140         shader_source += shader_start;
2141
2142         /* End main */
2143         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2144
2145         /* Execute test */
2146         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2147 }
2148
2149 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors1
2150  * array tests, and attempts to compile each test shader, for both
2151  * vertex and fragment shaders.
2152  *
2153  * @tparam API               Tested API descriptor
2154  *
2155  * @param tested_shader_type The type of shader that is being tested
2156  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2157  */
2158 template <class API>
2159 void ConstructorsAndUnsizedDeclInvalidConstructors1<API>::test_shader_compilation(
2160         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2161 {
2162         int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
2163
2164         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2165         {
2166                 _supported_variable_types_map_const_iterator var_iterator =
2167                         supported_variable_types_map.find(opaque_var_types[var_type_index]);
2168
2169                 if (var_iterator != supported_variable_types_map.end())
2170                 {
2171                         std::string base_variable_string =
2172                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler1;\n" +
2173                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler2;\n" +
2174                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler3;\n" +
2175                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler4;\n\n";
2176
2177                         std::string shader_source = base_variable_string + shader_start;
2178                         shader_source += "    const " + var_iterator->second.type + "[2][2] x = " + var_iterator->second.type +
2179                                                          "[2][2](" + var_iterator->second.type + "[2](my_sampler1, my_sampler2), " +
2180                                                          var_iterator->second.type + "[2](my_sampler3, my_sampler4));\n\n";
2181
2182                         /* End main */
2183                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2184
2185                         /* Execute test */
2186                         this->execute_negative_test(tested_shader_type, shader_source);
2187                 } /* if var_type iterator found */
2188                 else
2189                 {
2190                         TCU_FAIL("Type not found.");
2191                 }
2192         } /* for (int var_type_index = 0; ...) */
2193 }
2194
2195 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors2
2196  * array tests, and attempts to compile each test shader, for both
2197  * vertex and fragment shaders.
2198  *
2199  * @tparam API               Tested API descriptor
2200  *
2201  * @param tested_shader_type The type of shader that is being tested
2202  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2203  */
2204 template <class API>
2205 void ConstructorsAndUnsizedDeclInvalidConstructors2<API>::test_shader_compilation(
2206         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2207 {
2208         std::string invalid_initializers[] = { "    int x[2][2][0]; \n", "    int x[2][0][2]; \n", "    int x[0][2][2]; \n",
2209                                                                                    "    int x[2][0][0]; \n", "    int x[0][2][0]; \n", "    int x[0][0][2]; \n",
2210                                                                                    "    int x[0][0][0]; \n" };
2211
2212         for (size_t invalid_initializers_index = 0;
2213                  invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]);
2214                  invalid_initializers_index++)
2215         {
2216                 std::string shader_source;
2217
2218                 shader_source = shader_start;
2219                 shader_source += invalid_initializers[invalid_initializers_index];
2220
2221                 /* End main */
2222                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2223
2224                 /* Execute test */
2225                 this->execute_negative_test(tested_shader_type, shader_source);
2226         } /* for (int invalid_initializers_index = 0; ...) */
2227 }
2228
2229 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors3
2230  * array tests, and attempts to compile each test shader, for both
2231  * vertex and fragment shaders.
2232  *
2233  * @tparam API               Tested API descriptor
2234  *
2235  * @param tested_shader_type The type of shader that is being tested
2236  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2237  */
2238 template <class API>
2239 void ConstructorsAndUnsizedDeclInvalidConstructors3<API>::test_shader_compilation(
2240         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2241 {
2242         std::string invalid_initializers[] = { "    int x[2][2][-1]; \n",  "    int x[2][-1][2]; \n",
2243                                                                                    "    int x[-1][2][2]; \n",  "    int x[2][-1][-1]; \n",
2244                                                                                    "    int x[-1][2][-1]; \n", "    int x[-1][-1][2]; \n",
2245                                                                                    "    int x[-1][-1][-1]; \n" };
2246
2247         for (size_t invalid_initializers_index = 0;
2248                  invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]);
2249                  invalid_initializers_index++)
2250         {
2251                 std::string shader_source;
2252
2253                 shader_source = shader_start;
2254                 shader_source += invalid_initializers[invalid_initializers_index];
2255
2256                 /* End main */
2257                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2258
2259                 /* Execute test */
2260                 this->execute_negative_test(tested_shader_type, shader_source);
2261         } /* for (int invalid_initializers_index = 0; ...) */
2262 }
2263
2264 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors4
2265  * array tests, and attempts to compile each test shader, for both
2266  * vertex and fragment shaders.
2267  *
2268  * @tparam API               Tested API descriptor
2269  *
2270  * @param tested_shader_type The type of shader that is being tested
2271  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2272  */
2273 template <class API>
2274 void ConstructorsAndUnsizedDeclInvalidConstructors4<API>::test_shader_compilation(
2275         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2276 {
2277         std::string invalid_initializers[] = { "    int x[2][2][a]; \n", "    int x[2][a][2]; \n", "    int x[a][2][2]; \n",
2278                                                                                    "    int x[2][a][a]; \n", "    int x[a][2][a]; \n", "    int x[a][a][2]; \n",
2279                                                                                    "    int x[a][a][a]; \n" };
2280         std::string non_constant_variable_init = "    uint a = 2u;\n";
2281
2282         for (size_t invalid_initializers_index = 0;
2283                  invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]);
2284                  invalid_initializers_index++)
2285         {
2286                 std::string shader_source;
2287
2288                 shader_source = shader_start;
2289                 shader_source += non_constant_variable_init;
2290                 shader_source += invalid_initializers[invalid_initializers_index];
2291
2292                 /* End main */
2293                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2294
2295                 /* Execute test */
2296                 this->execute_negative_test(tested_shader_type, shader_source);
2297         } /* for (int invalid_initializers_index = 0; ...) */
2298 }
2299
2300 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructorSizing1
2301  * array tests, and attempts to compile each test shader, for both
2302  * vertex and fragment shaders.
2303  *
2304  * @tparam API               Tested API descriptor
2305  *
2306  * @param tested_shader_type The type of shader that is being tested
2307  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2308  */
2309 template <class API>
2310 void ConstructorsAndUnsizedDeclConstructorSizing1<API>::test_shader_compilation(
2311         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2312 {
2313         std::string valid_size_initializers[] = { "[1][1][1][]", "[1][1][][1]", "[1][][1][1]", "[][1][1][1]", "[1][1][][]",
2314                                                                                           "[1][][1][]",  "[][1][1][]",  "[1][][][1]",  "[][1][][1]",  "[][][1][1]",
2315                                                                                           "[1][][][]",   "[][1][][]",   "[][][1][]",   "[][][][1]",   "[][][][]" };
2316
2317         for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
2318         {
2319                 _supported_variable_types_map_const_iterator var_iterator =
2320                         supported_variable_types_map.find(API::var_types[var_type_index]);
2321
2322                 if (var_iterator != supported_variable_types_map.end())
2323                 {
2324                         for (size_t valid_size_initializers_index = 0;
2325                                  valid_size_initializers_index < sizeof(valid_size_initializers) / sizeof(valid_size_initializers[0]);
2326                                  valid_size_initializers_index++)
2327                         {
2328                                 std::string shader_source;
2329                                 std::string variable_constructor =
2330                                         "    " + var_iterator->second.type + " x" + valid_size_initializers[valid_size_initializers_index] +
2331                                         " = " + var_iterator->second.type + "[1][1][1][1](" + var_iterator->second.type + "[1][1][1](" +
2332                                         var_iterator->second.type + "[1][1](" + var_iterator->second.type + "[1](" +
2333                                         var_iterator->second.initializer_with_zeroes + "))));\n";
2334
2335                                 shader_source = shader_start;
2336                                 shader_source += variable_constructor;
2337
2338                                 /* End main */
2339                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2340
2341                                 /* Execute test */
2342                                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2343                         } /* for (int valid_size_initializers_index = 0; ...) */
2344                 }        /* if var_type iterator found */
2345                 else
2346                 {
2347                         TCU_FAIL("Type not found.");
2348                 }
2349         } /* for (int var_type_index = 0; ...) */
2350 }
2351
2352 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructorSizing2
2353  * array tests, and attempts to compile each test shader, for both
2354  * vertex and fragment shaders.
2355  *
2356  * @tparam API               Tested API descriptor
2357  *
2358  * @param tested_shader_type The type of shader that is being tested
2359  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2360  */
2361 template <class API>
2362 void ConstructorsAndUnsizedDeclConstructorSizing2<API>::test_shader_compilation(
2363         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2364 {
2365         std::string shader_source = shader_start;
2366
2367         shader_source += "    float[] a ="
2368                                          "            float[](1.0, 2.0),"
2369                                          "        b[] ="
2370                                          "         float[][]("
2371                                          "             float[](1.0, 2.0),"
2372                                          "             float[](3.0, 4.0)"
2373                                          "         ),"
2374                                          "        c[][] ="
2375                                          "         float[][][]("
2376                                          "             float[][]("
2377                                          "                 float[](1.0),"
2378                                          "                 float[](2.0)"
2379                                          "             )"
2380                                          "         ),"
2381                                          "        d[][][] ="
2382                                          "         float[][][][]("
2383                                          "             float[][][]("
2384                                          "                 float[][]("
2385                                          "                     float[](1.0, 2.0),"
2386                                          "                     float[](3.0, 4.0),"
2387                                          "                     float[](5.0, 6.0)"
2388                                          "                 )"
2389                                          "             ),"
2390                                          "             float[][][]("
2391                                          "                 float[][]("
2392                                          "                     float[](1.0, 2.0),"
2393                                          "                     float[](3.0, 4.0),"
2394                                          "                     float[](5.0, 6.0)"
2395                                          "                 )"
2396                                          "             )"
2397                                          "         ),"
2398                                          "        e[][][][]="
2399                                          "         float[][][][][]("
2400                                          "             float[][][][]("
2401                                          "                 float[][][]("
2402                                          "                     float[][]("
2403                                          "                         float[](1.0),"
2404                                          "                         float[](2.0)"
2405                                          "                     ),"
2406                                          "                     float[][]("
2407                                          "                         float[](1.0),"
2408                                          "                         float[](2.0)"
2409                                          "                     ),"
2410                                          "                     float[][]("
2411                                          "                         float[](1.0),"
2412                                          "                         float[](2.0)"
2413                                          "                     )"
2414                                          "                 ),"
2415                                          "                 float[][][]("
2416                                          "                     float[][]("
2417                                          "                         float[](1.0),"
2418                                          "                         float[](2.0)"
2419                                          "                     ),"
2420                                          "                     float[][]("
2421                                          "                         float[](1.0),"
2422                                          "                         float[](2.0)"
2423                                          "                     ),"
2424                                          "                     float[][]("
2425                                          "                         float[](1.0),"
2426                                          "                         float[](2.0)"
2427                                          "                     )"
2428                                          "                 )"
2429                                          "             )"
2430                                          "         ),"
2431                                          "        f[][][][][]="
2432                                          "         float[][][][][][]("
2433                                          "             float[][][][][]("
2434                                          "                 float[][][][]("
2435                                          "                     float[][][]("
2436                                          "                         float[][]("
2437                                          "                             float[](1.0)"
2438                                          "                         )"
2439                                          "                     )"
2440                                          "                 )"
2441                                          "             )"
2442                                          "         ),"
2443                                          "        g[][][][][][]="
2444                                          "         float[][][][][][][]("
2445                                          "             float[][][][][][]("
2446                                          "                 float[][][][][]("
2447                                          "                     float[][][][]("
2448                                          "                         float[][][]("
2449                                          "                             float[][]("
2450                                          "                                 float[](1.0)"
2451                                          "                             )"
2452                                          "                         )"
2453                                          "                     )"
2454                                          "                 )"
2455                                          "             )"
2456                                          "         ),"
2457                                          "        h[][][][][][][]="
2458                                          "         float[][][][][][][][]("
2459                                          "             float[][][][][][][]("
2460                                          "                 float[][][][][][]("
2461                                          "                     float[][][][][]("
2462                                          "                         float[][][][]("
2463                                          "                             float[][][]("
2464                                          "                                 float[][]("
2465                                          "                                     float[](1.0)"
2466                                          "                                 )"
2467                                          "                             )"
2468                                          "                         )"
2469                                          "                     )"
2470                                          "                 )"
2471                                          "             )"
2472                                          "         );\n";
2473
2474         /* End main */
2475         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2476
2477         /* Execute test */
2478         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2479 }
2480
2481 /* Constructs a suitable constructor for the specified number of dimensions.
2482  *
2483  * @tparam API            Tested API descriptor
2484  *
2485  * @param var_type        The type of the variable
2486  * @param dimension_index The current recursion level (counts down)
2487  * @param init_string     The initialisation string
2488  */
2489 template <class API>
2490 std::string ConstructorsAndUnsizedDeclStructConstructors<API>::recursively_initialise(std::string var_type,
2491                                                                                                                                                                           size_t          dimension_index,
2492                                                                                                                                                                           std::string init_string)
2493 {
2494         std::string temp_string;
2495
2496         if (dimension_index == 0)
2497         {
2498                 temp_string = var_type + "(" + init_string + ")";
2499         }
2500         else
2501         {
2502                 std::string prefix = "\n";
2503
2504                 for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
2505                 {
2506                         prefix += "    ";
2507                 }
2508
2509                 prefix += this->extend_string(var_type, "[]", dimension_index);
2510                 prefix += "(";
2511
2512                 for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
2513                 {
2514                         temp_string += prefix;
2515                         temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
2516                         prefix = ", ";
2517
2518                         if (dimension_index == 1)
2519                         {
2520                                 break;
2521                         }
2522                 }
2523                 temp_string += ")";
2524         }
2525
2526         return temp_string;
2527 }
2528
2529 /* Generates the shader source code for the ConstructorsAndUnsizedDeclStructConstructors
2530  * array tests, and attempts to compile each test shader, for both
2531  * vertex and fragment shaders.
2532  *
2533  * @tparam API               Tested API descriptor
2534  *
2535  * @param tested_shader_type The type of shader that is being tested
2536  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2537  */
2538 template <class API>
2539 void ConstructorsAndUnsizedDeclStructConstructors<API>::test_shader_compilation(
2540         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2541 {
2542         std::string example_structure_definition("struct light {\n"
2543                                                                                          "    float intensity;\n"
2544                                                                                          "    int position;\n"
2545                                                                                          "};\n");
2546         std::string example_structure_object("    light my_light_variable");
2547
2548         for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2549         {
2550                 std::string base_variable_string = this->extend_string(example_structure_object, "[]", max_dimension_index);
2551                 base_variable_string += " = ";
2552                 base_variable_string += recursively_initialise("light", max_dimension_index, "1.0, 2");
2553                 base_variable_string += ";\n\n";
2554
2555                 std::string shader_source = example_structure_definition + shader_start + base_variable_string;
2556
2557                 /* End main */
2558                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2559
2560                 /* Execute test */
2561                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2562         } /* for (int max_dimension_index = 2; ...) */
2563 }
2564
2565 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays1
2566  * array tests, and attempts to compile each test shader, for both
2567  * vertex and fragment shaders.
2568  *
2569  * @tparam API               Tested API descriptor
2570  *
2571  * @param tested_shader_type The type of shader that is being tested
2572  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2573  */
2574 template <class API>
2575 void ConstructorsAndUnsizedDeclUnsizedArrays1<API>::test_shader_compilation(
2576         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2577 {
2578         std::string base_variable_string;
2579
2580         for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2581         {
2582                 base_variable_string = this->extend_string("    int x", "[]", max_dimension_index);
2583                 base_variable_string += ";\n\n";
2584
2585                 std::string shader_source = shader_start + base_variable_string;
2586
2587                 /* End main */
2588                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2589
2590                 /* Execute test */
2591                 this->execute_negative_test(tested_shader_type, shader_source);
2592         } /* for (int max_dimension_index = 2; ...) */
2593 }
2594
2595 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays2
2596  * array tests, and attempts to compile each test shader, for both
2597  * vertex and fragment shaders.
2598  *
2599  * @tparam API               Tested API descriptor
2600  *
2601  * @param tested_shader_type The type of shader that is being tested
2602  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2603  */
2604 template <class API>
2605 void ConstructorsAndUnsizedDeclUnsizedArrays2<API>::test_shader_compilation(
2606         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2607 {
2608         std::string input[] = { "    float [] x = float[](1), y;\n\n" };
2609
2610         for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
2611         {
2612                 std::string shader_source;
2613
2614                 shader_source += shader_start;
2615                 shader_source += input[string_index];
2616
2617                 /* End main */
2618                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2619
2620                 /* Execute test */
2621                 EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION, tested_shader_type, shader_source);
2622         } /* for (int string_index = 0; ...) */
2623 }
2624
2625 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays3
2626  * array tests, and attempts to compile each test shader, for both
2627  * vertex and fragment shaders.
2628  *
2629  * @tparam API               Tested API descriptor
2630  *
2631  * @param tested_shader_type The type of shader that is being tested
2632  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2633  */
2634 template <class API>
2635 void ConstructorsAndUnsizedDeclUnsizedArrays3<API>::test_shader_compilation(
2636         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2637 {
2638         std::string base_variable_string("    float[][] x = mat4(0);\n\n");
2639
2640         std::string shader_source = shader_start + base_variable_string;
2641
2642         /* End main */
2643         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2644
2645         /* Execute test */
2646         this->execute_negative_test(tested_shader_type, shader_source);
2647 }
2648
2649 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays4
2650  * array tests, and attempts to compile each test shader, for both
2651  * vertex and fragment shaders.
2652  *
2653  * @tparam API               Tested API descriptor
2654  *
2655  * @param tested_shader_type The type of shader that is being tested
2656  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2657  */
2658 template <class API>
2659 void ConstructorsAndUnsizedDeclUnsizedArrays4<API>::test_shader_compilation(
2660         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2661 {
2662         std::string example_struct("struct light {\n"
2663                                                            "    float[][] intensity;\n"
2664                                                            "    int       position;\n"
2665                                                            "} myLight;\n\n");
2666
2667         std::string shader_source = example_struct + shader_start;
2668
2669         /* End main */
2670         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2671
2672         /* Execute test */
2673         this->execute_negative_test(tested_shader_type, shader_source);
2674 }
2675
2676 /* Constructs a suitable constructor for the specified number of dimensions.
2677  *
2678  * @tparam API            Tested API descriptor
2679  *
2680  * @param dimension_index The current recursion level (counts down)
2681  * @param init_string     The initialisation string
2682  */
2683 template <class API>
2684 std::string ExpressionsAssignment1<API>::recursively_initialise(std::string var_type, size_t dimension_index,
2685                                                                                                                                 std::string init_string)
2686 {
2687         std::string temp_string;
2688
2689         if (dimension_index == 0)
2690         {
2691                 temp_string = init_string;
2692         }
2693         else
2694         {
2695                 std::string prefix = "\n";
2696
2697                 for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
2698                 {
2699                         prefix += "    ";
2700                 }
2701
2702                 prefix += this->extend_string(var_type, "[]", dimension_index);
2703                 prefix += "(";
2704                 for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
2705                 {
2706                         temp_string += prefix;
2707                         temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
2708                         prefix = ", ";
2709                         if (dimension_index == 1)
2710                         {
2711                                 break;
2712                         }
2713                 }
2714                 temp_string += ")";
2715         }
2716
2717         return temp_string;
2718 }
2719
2720 /* Generates the shader source code for the ExpressionsAssignment1
2721  * array tests, and attempts to compile each test shader, for both
2722  * vertex and fragment shaders.
2723  *
2724  * @tparam API               Tested API descriptor
2725  *
2726  * @param tested_shader_type The type of shader that is being tested
2727  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2728  */
2729 template <class API>
2730 void ExpressionsAssignment1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
2731 {
2732         for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2733         {
2734                 std::string prefix = "(";
2735                 std::string base_variable_string;
2736
2737                 base_variable_string += this->extend_string("    float x", "[2]", max_dimension_index);
2738                 base_variable_string += " = ";
2739                 base_variable_string += recursively_initialise("float", max_dimension_index, "4.0, 6.0");
2740                 base_variable_string += ";\n";
2741                 base_variable_string += this->extend_string("    float y", "[2]", max_dimension_index);
2742                 base_variable_string += " = ";
2743                 base_variable_string += recursively_initialise("float", max_dimension_index, "1.0, 2.0");
2744                 base_variable_string += ";\n\n";
2745
2746                 std::string shader_source = shader_start + base_variable_string;
2747
2748                 shader_source += "    x = y;\n";
2749
2750                 /* End main */
2751                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2752
2753                 /* Execute test */
2754                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2755         } /* for (int max_dimension_index = 2; ...) */
2756 }
2757
2758 /* Generates the shader source code for the ExpressionsAssignment2
2759  * array tests, and attempts to compile each test shader, for both
2760  * vertex and fragment shaders.
2761  *
2762  * @tparam API               Tested API descriptor
2763  *
2764  * @param tested_shader_type The type of shader that is being tested
2765  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2766  */
2767 template <class API>
2768 void ExpressionsAssignment2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
2769 {
2770         std::string shader_body("    float a[2] = float[](1.0, 2.0);\n"
2771                                                         "    float b[2][2] = float[][](float[](1.0, 2.0), float[](1.0, 2.0));\n"
2772                                                         "    float c[2][2][2] = float[][][]("
2773                                                         "float[][](float[](1.0, 2.0), float[](1.0, 2.0)),"
2774                                                         "float[][](float[](1.0, 2.0), float[](1.0, 2.0)));\n"
2775                                                         "    float d[2][2][2][2] = float[][][][]("
2776                                                         "float[][][]("
2777                                                         "float[][](float[](1.0, 2.0), float[](1.0, 2.0)), "
2778                                                         "float[][](float[](1.0, 2.0), float[](1.0, 2.0))),"
2779                                                         "float[][][]("
2780                                                         "float[][](float[](1.0, 2.0), float[](1.0, 2.0)), "
2781                                                         "float[][](float[](1.0, 2.0), float[](1.0, 2.0))));\n\n");
2782
2783         std::string variable_basenames[] = { "a", "b", "c", "d" };
2784         int                     number_of_elements   = sizeof(variable_basenames) / sizeof(variable_basenames[0]);
2785
2786         for (int variable_index = 0; variable_index < number_of_elements; variable_index++)
2787         {
2788                 for (int value_index = variable_index; value_index < number_of_elements; value_index++)
2789                 {
2790                         std::string shader_source = shader_start + shader_body;
2791
2792                         /* Avoid the situation when a variable is assign to itself. */
2793                         if (variable_index != value_index)
2794                         {
2795                                 shader_source += "    " + variable_basenames[variable_index] + " = " + variable_basenames[value_index];
2796                                 shader_source += ";\n";
2797
2798                                 /* End main */
2799                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2800
2801                                 /* Execute test */
2802                                 this->execute_negative_test(tested_shader_type, shader_source);
2803                         } /* if(variable_index != value_index) */
2804                 }        /* for (int value_index = variable_index; ...) */
2805         }                 /* for (int variable_index = 0; ...) */
2806 }
2807
2808 /* Generates the shader source code for the ExpressionsAssignment3
2809  * array tests, and attempts to compile each test shader, for both
2810  * vertex and fragment shaders.
2811  *
2812  * @tparam API               Tested API descriptor
2813  *
2814  * @param tested_shader_type The type of shader that is being tested
2815  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2816  */
2817 template <class API>
2818 void ExpressionsAssignment3<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
2819 {
2820         std::string prefix, base_variable_string;
2821
2822         const int test_array_dimensions = 4;
2823
2824         prefix = this->extend_string("    float a", "[1]", 4);
2825         prefix += " = float[][][][](\n"
2826                           "       float[][][](\n"
2827                           "           float[][](\n"
2828                           "               float[](1.0))));\n";
2829
2830         prefix += "    float b";
2831
2832         for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
2833         {
2834                 base_variable_string = prefix;
2835
2836                 for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
2837                 {
2838                         if (permutation & (1 << sub_script_index))
2839                         {
2840                                 base_variable_string += "[1]";
2841                         }
2842                         else
2843                         {
2844                                 base_variable_string += "[2]";
2845                         }
2846                 }
2847
2848                 base_variable_string += ";\n\n";
2849
2850                 if (permutation != (1 << test_array_dimensions) - 1)
2851                 {
2852                         std::string shader_source = shader_start + base_variable_string;
2853
2854                         shader_source += "    b = a;\n";
2855
2856                         /* End main */
2857                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2858
2859                         /* Execute test */
2860                         this->execute_negative_test(tested_shader_type, shader_source);
2861                 } /* if (permutation != (1 << test_array_dimensions) - 1) */
2862         }        /* for (int permutation = 0; ...) */
2863 }
2864
2865 /* Generates the shader source code for the ExpressionsTypeRestrictions1
2866  * array tests, and attempts to compile each test shader, for both
2867  * vertex and fragment shaders.
2868  *
2869  * @tparam API               Tested API descriptor
2870  *
2871  * @param tested_shader_type The type of shader that is being tested
2872  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2873  */
2874 template <class API>
2875 void ExpressionsTypeRestrictions1<API>::test_shader_compilation(
2876         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2877 {
2878         int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
2879
2880         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2881         {
2882                 _supported_variable_types_map_const_iterator var_iterator =
2883                         supported_variable_types_map.find(opaque_var_types[var_type_index]);
2884
2885                 if (var_iterator != supported_variable_types_map.end())
2886                 {
2887                         std::string shader_source =
2888                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " var1[2][2];\n"
2889                                                                                                                                                                                                 "uniform " +
2890                                 var_iterator->second.precision + " " + var_iterator->second.type + " var2[2][2];\n\n";
2891                         shader_source += shader_start;
2892
2893                         shader_source += "    var1 = var2;\n";
2894
2895                         /* End main */
2896                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2897
2898                         /* Execute test */
2899                         this->execute_negative_test(tested_shader_type, shader_source);
2900                 } /* if var_type iterator found */
2901                 else
2902                 {
2903                         TCU_FAIL("Type not found.");
2904                 }
2905         } /* for (int var_type_index = 0; ...) */
2906 }
2907
2908 /* Generates the shader source code for the ExpressionsTypeRestrictions2
2909  * array tests, and attempts to compile each test shader, for both
2910  * vertex and fragment shaders.
2911  *
2912  * @tparam API               Tested API descriptor
2913  *
2914  * @param tested_shader_type The type of shader that is being tested
2915  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2916  */
2917 template <class API>
2918 void ExpressionsTypeRestrictions2<API>::test_shader_compilation(
2919         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2920 {
2921         int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
2922
2923         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2924         {
2925                 _supported_variable_types_map_const_iterator var_iterator =
2926                         supported_variable_types_map.find(opaque_var_types[var_type_index]);
2927
2928                 if (var_iterator != supported_variable_types_map.end())
2929                 {
2930                         std::string shader_source =
2931                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " sampler1;\n"
2932                                                                                                                                                                                                 "uniform " +
2933                                 var_iterator->second.precision + " " + var_iterator->second.type + " sampler2;\n"
2934                                                                                                                                                                    "uniform " +
2935                                 var_iterator->second.precision + " " + var_iterator->second.type + " sampler3;\n"
2936                                                                                                                                                                    "uniform " +
2937                                 var_iterator->second.precision + " " + var_iterator->second.type + " sampler4;\n"
2938                                                                                                                                                                    "struct light1 {\n"
2939                                                                                                                                                                    "    " +
2940                                 var_iterator->second.type + " var1[2][2];\n"
2941                                                                                         "};\n\n";
2942                         shader_source += shader_start;
2943
2944                         shader_source +=
2945                                 ("    light1 x = light1(" + var_iterator->second.type + "[][](" + var_iterator->second.type +
2946                                  "[](sampler1, sampler2), " + var_iterator->second.type + "[](sampler3, sampler4)));\n");
2947                         shader_source += "    light1 y = x;\n\n";
2948
2949                         /* End main */
2950                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2951
2952                         /* Execute test */
2953                         this->execute_negative_test(tested_shader_type, shader_source);
2954                 } /* if var_type iterator found */
2955                 else
2956                 {
2957                         TCU_FAIL("Type not found.");
2958                 }
2959         } /* for (int var_type_index = 0; ...) */
2960 }
2961
2962 /* Generates the shader source code for the ExpressionsIndexingScalar1
2963  * array tests, and attempts to compile each test shader, for both
2964  * vertex and fragment shaders.
2965  *
2966  * @tparam API               Tested API descriptor
2967  *
2968  * @param tested_shader_type The type of shader that is being tested
2969  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2970  */
2971 template <class API>
2972 void ExpressionsIndexingScalar1<API>::test_shader_compilation(
2973         typename TestCaseBase<API>::TestShaderType tested_shader_type)
2974 {
2975         for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
2976         {
2977                 _supported_variable_types_map_const_iterator var_iterator =
2978                         supported_variable_types_map.find(API::var_types[var_type_index]);
2979
2980                 if (var_iterator != supported_variable_types_map.end())
2981                 {
2982                         std::string shader_source = shader_start + "    " + var_iterator->second.type + " x[1][2][3][4];\n\n";
2983
2984                         shader_source += "    for (uint i = 0u; i < 2u; i++) {\n";
2985                         shader_source += "        for (uint j = 0u; j < 3u; j++) {\n";
2986                         shader_source += "            for (uint k = 0u; k < 4u; k++) {\n";
2987                         shader_source += "                x[0][i][j][k] = " + var_iterator->second.initializer_with_ones + ";\n";
2988                         shader_source += "            }\n";
2989                         shader_source += "        }\n";
2990                         shader_source += "    }\n";
2991
2992                         /* End main */
2993                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2994
2995                         /* Execute test */
2996                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2997                 } /* if var_type iterator found */
2998                 else
2999                 {
3000                         TCU_FAIL("Type not found.");
3001                 }
3002         }
3003 }
3004
3005 /* Generates the shader source code for the ExpressionsIndexingScalar2
3006  * array tests, and attempts to compile each test shader, for both
3007  * vertex and fragment shaders.
3008  *
3009  * @tparam API               Tested API descriptor
3010  *
3011  * @param tested_shader_type The type of shader that is being tested
3012  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3013  */
3014 template <class API>
3015 void ExpressionsIndexingScalar2<API>::test_shader_compilation(
3016         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3017 {
3018         std::string base_shader_string, shader_source;
3019
3020         // This test tests arrays with 4 dimensions, e.g. x[1][1][1][1]
3021         const int test_array_dimensions = 4;
3022
3023         base_shader_string = "float a[1][2][3][4];\n";
3024         base_shader_string += "float b = 2.0;\n\n";
3025         base_shader_string += shader_start;
3026
3027         // There are 16 permutations, so loop 4x4 times.
3028         for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
3029         {
3030                 shader_source = base_shader_string + "    a"; // a var called 'a'
3031
3032                 for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
3033                 {
3034                         /* If any bit is set for a particular number then add
3035                          * a valid array sub_script at that place, otherwise
3036                          * add an invalid array sub_script. */
3037                         if (permutation & (1 << sub_script_index))
3038                         {
3039                                 shader_source += "[0]";
3040                         }
3041                         else
3042                         {
3043                                 shader_source += "[-1]";
3044                         }
3045                 }
3046
3047                 shader_source += " = b;\n";
3048
3049                 if (permutation != (1 << test_array_dimensions) - 1)
3050                 {
3051                         /* End main */
3052                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3053
3054                         /* Execute test */
3055                         this->execute_negative_test(tested_shader_type, shader_source);
3056                 } /* if (permutation != (1 << test_array_dimensions) - 1) */
3057         }        /* for (int permutation = 0; ...) */
3058 }
3059
3060 /* Generates the shader source code for the ExpressionsIndexingScalar3
3061  * array tests, and attempts to compile each test shader, for both
3062  * vertex and fragment shaders.
3063  *
3064  * @tparam API               Tested API descriptor
3065  *
3066  * @param tested_shader_type The type of shader that is being tested
3067  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3068  */
3069 template <class API>
3070 void ExpressionsIndexingScalar3<API>::test_shader_compilation(
3071         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3072 {
3073         std::string base_shader_string;
3074         std::string shader_source;
3075         const int   test_array_dimensions = 4;
3076
3077         base_shader_string = "float a[1][2][3][4];\n";
3078         base_shader_string += "float b = 2.0;\n\n";
3079         base_shader_string += shader_start;
3080
3081         for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
3082         {
3083                 shader_source = base_shader_string + "    a";
3084
3085                 for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
3086                 {
3087                         if (permutation & (1 << sub_script_index))
3088                         {
3089                                 shader_source += "[0]";
3090                         }
3091                         else
3092                         {
3093                                 shader_source += "[4]";
3094                         }
3095                 }
3096
3097                 shader_source += " = b;\n";
3098
3099                 if (permutation != (1 << test_array_dimensions) - 1)
3100                 {
3101                         /* End main */
3102                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3103
3104                         /* Execute test */
3105                         this->execute_negative_test(tested_shader_type, shader_source);
3106                 } /* if (permutation != (1 << test_array_dimensions) - 1) */
3107         }        /* for (int permutation = 0; ...) */
3108 }
3109
3110 /* Generates the shader source code for the ExpressionsIndexingScalar4
3111  * array tests, and attempts to compile each test shader, for both
3112  * vertex and fragment shaders.
3113  *
3114  * @tparam API               Tested API descriptor
3115  *
3116  * @param tested_shader_type The type of shader that is being tested
3117  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3118  */
3119 template <class API>
3120 void ExpressionsIndexingScalar4<API>::test_shader_compilation(
3121         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3122 {
3123         std::string base_shader_string;
3124         std::string shader_source;
3125
3126         const int test_array_dimensions = 4;
3127
3128         base_shader_string = "float a[1][2][3][4];\n";
3129         base_shader_string += "float b = 2.0;\n\n";
3130         base_shader_string += shader_start;
3131
3132         for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
3133         {
3134                 shader_source = base_shader_string + "    a";
3135
3136                 for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
3137                 {
3138                         if (permutation & (1 << sub_script_index))
3139                         {
3140                                 shader_source += "[0]";
3141                         }
3142                         else
3143                         {
3144                                 shader_source += "[]";
3145                         }
3146                 }
3147
3148                 shader_source += " = b;\n";
3149
3150                 if (permutation != (1 << test_array_dimensions) - 1)
3151                 {
3152                         /* End main */
3153                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3154
3155                         /* Execute test */
3156                         this->execute_negative_test(tested_shader_type, shader_source);
3157                 } /* if (permutation != (1 << test_array_dimensions) - 1) */
3158         }        /* for (int permutation = 0; ...) */
3159 }
3160
3161 /* Generates the shader source code for the ExpressionsIndexingArray1
3162  * array tests, and attempts to compile each test shader, for both
3163  * vertex and fragment shaders.
3164  *
3165  * @tparam API               Tested API descriptor
3166  *
3167  * @param tested_shader_type The type of shader that is being tested
3168  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3169  */
3170 template <class API>
3171 void ExpressionsIndexingArray1<API>::test_shader_compilation(
3172         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3173 {
3174         std::string shader_source;
3175         std::string variable_declaration = "float x[1][1][1][1][1][1][1][1];\n\n";
3176
3177         std::string variable_initializations[] = {
3178                 "x[0]                      = float[1][1][1][1][1][1][1]("
3179                 "float[1][1][1][1][1][1](float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0)))))));"
3180                 "\n",
3181                 "x[0][0]                   = "
3182                 "float[1][1][1][1][1][1](float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0))))));"
3183                 "\n",
3184                 "x[0][0][0]                = "
3185                 "float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0)))));\n",
3186                 "x[0][0][0][0]             = float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0))));\n",
3187                 "x[0][0][0][0][0]          = float[1][1][1](float[1][1](float[1](1.0)));\n",
3188                 "x[0][0][0][0][0][0]       = float[1][1](float[1](1.0));\n", "x[0][0][0][0][0][0][0]    = float[1](1.0);\n",
3189                 "x[0][0][0][0][0][0][0][0] = 1.0;\n"
3190         };
3191
3192         for (size_t string_index = 0; string_index < sizeof(variable_initializations) / sizeof(variable_initializations[0]);
3193                  string_index++)
3194         {
3195                 shader_source = variable_declaration + shader_start;
3196                 shader_source += "    " + variable_initializations[string_index];
3197
3198                 /* End main */
3199                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3200
3201                 /* Execute test */
3202                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3203         } /* for (int string_index = 0; ...) */
3204 }
3205
3206 /* Constructs a suitable constructor for the specified number of dimensions.
3207  *
3208  * @tparam API            Tested API descriptor
3209  *
3210  * @param dimension_index The current recursion level (counts down)
3211  * @param init_string     The initialisation string
3212  */
3213 template <class API>
3214 std::string ExpressionsIndexingArray2<API>::recursively_initialise(std::string var_type, size_t dimension_index,
3215                                                                                                                                    std::string init_string)
3216 {
3217         std::string temp_string;
3218
3219         if (dimension_index == 0)
3220         {
3221                 temp_string = init_string;
3222         }
3223         else
3224         {
3225                 std::string prefix = "\n";
3226
3227                 for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
3228                 {
3229                         prefix += "    ";
3230                 }
3231
3232                 prefix += this->extend_string(var_type, "[]", dimension_index);
3233                 prefix += "(";
3234                 for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
3235                 {
3236                         temp_string += prefix;
3237                         temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
3238                         prefix = ", ";
3239                         if (dimension_index == 1)
3240                         {
3241                                 break;
3242                         }
3243                 }
3244                 temp_string += ")";
3245         }
3246
3247         return temp_string;
3248 }
3249
3250 /* Generates the shader source code for the ExpressionsIndexingArray2
3251  * array tests, and attempts to compile each test shader, for both
3252  * vertex and fragment shaders.
3253  *
3254  * @tparam API               Tested API descriptor
3255  *
3256  * @param tested_shader_type The type of shader that is being tested
3257  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3258  */
3259 template <class API>
3260 void ExpressionsIndexingArray2<API>::test_shader_compilation(
3261         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3262 {
3263         std::string variable_initialiser = "    float[](float[](float(float(float(float(float(float(1.0))))))));\n";
3264
3265         std::string x_variable_initializaton =
3266                 "    float x[2][2][2][2][2][2][2][1] = " + recursively_initialise("float", API::MAX_ARRAY_DIMENSIONS, "1.0") +
3267                 ";\n";
3268         std::string y_variable_initializaton =
3269                 "    float y[2][2][2][2][2][2][2][1] = " + recursively_initialise("float", API::MAX_ARRAY_DIMENSIONS, "1.0") +
3270                 ";\n";
3271
3272         std::string shader_code_common_part = shader_start + x_variable_initializaton + y_variable_initializaton;
3273
3274         for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
3275         {
3276                 std::string iteration_specific_shader_code_part;
3277
3278                 iteration_specific_shader_code_part += this->extend_string("    x", "[0]", max_dimension_index);
3279                 iteration_specific_shader_code_part += " = ";
3280                 iteration_specific_shader_code_part += this->extend_string("y", "[0]", max_dimension_index);
3281                 iteration_specific_shader_code_part += ";\n";
3282
3283                 std::string shader_source = shader_code_common_part + iteration_specific_shader_code_part;
3284
3285                 /* End main */
3286                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3287
3288                 /* Execute test */
3289                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3290         }
3291 }
3292
3293 /* Generates the shader source code for the ExpressionsIndexingArray3
3294  * array tests, and attempts to compile each test shader, for both
3295  * vertex and fragment shaders.
3296  *
3297  * @tparam API               Tested API descriptor
3298  *
3299  * @param tested_shader_type The type of shader that is being tested
3300  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3301  */
3302 template <class API>
3303 void ExpressionsIndexingArray3<API>::test_shader_compilation(
3304         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3305 {
3306         std::string input[] = { "    x[ivec2(0)] = 1.0;\n\n", "    x[ivec3(0)] = 1.0;\n\n", "    x[ivec4(0)] = 1.0;\n\n" };
3307
3308         for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
3309         {
3310                 std::string shader_source = shader_start + this->extend_string("    float x", "[2]", (int)string_index + 2) +
3311                                                                         ";\n\n" + input[string_index];
3312
3313                 /* End main */
3314                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3315
3316                 /* Execute test */
3317                 this->execute_negative_test(tested_shader_type, shader_source);
3318         } /* for (int string_index = 0; ...) */
3319 }
3320
3321 /* Generates the shader source code for the ExpressionsDynamicIndexing1
3322  * array tests, and attempts to compile each test shader, for both
3323  * vertex and fragment shaders.
3324  *
3325  * @tparam API               Tested API descriptor
3326  *
3327  * @param tested_shader_type The type of shader that is being tested
3328  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3329  */
3330 template <class API>
3331 void ExpressionsDynamicIndexing1<API>::test_shader_compilation(
3332         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3333 {
3334         std::string expression_type_declarations = "uniform int a;\n"
3335                                                                                            "const int b = 0;\n"
3336                                                                                            "int c = 0;\n"
3337                                                                                            "float x[2][2];\n";
3338
3339         std::string expressions[] = { "a", "b", "c", "0 + 1" };
3340         std::string shader_source;
3341
3342         for (size_t write_index = 0; write_index < sizeof(expressions) / sizeof(expressions[0]); write_index++)
3343         {
3344                 for (size_t read_index = 0; read_index < sizeof(expressions) / sizeof(expressions[0]); read_index++)
3345                 {
3346                         shader_source = expression_type_declarations;
3347                         shader_source += shader_start;
3348                         shader_source += "    x[";
3349                         shader_source += expressions[write_index];
3350                         shader_source += "][";
3351                         shader_source += expressions[read_index];
3352                         shader_source += "] = 1.0;\n\n";
3353
3354                         /* End main */
3355                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3356
3357                         /* Execute test */
3358                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3359                 } /* for (int read_index = 0; ...) */
3360         }        /* for (int write_index = 0; ...) */
3361 }
3362
3363 /* Generates the shader source code for the ExpressionsDynamicIndexing2
3364  * array tests, and attempts to compile each test shader, for both
3365  * vertex and fragment shaders.
3366  *
3367  * @tparam API               Tested API descriptor
3368  *
3369  * @param tested_shader_type The type of shader that is being tested
3370  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3371  */
3372 template <class API>
3373 void ExpressionsDynamicIndexing2<API>::test_shader_compilation(
3374         typename TestCaseBase<API>::TestShaderType tested_shader_type)
3375 {
3376         int                               num_var_types                           = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
3377         const std::string invalid_size_declarations[] = { "[0][0][0][y]", "[0][0][y][0]", "[0][y][0][0]", "[y][0][0][0]",
3378                                                                                                           "[0][0][y][y]", "[0][y][0][y]", "[y][0][0][y]", "[0][y][y][0]",
3379                                                                                                           "[y][0][y][0]", "[y][y][0][0]", "[0][y][y][y]", "[y][0][y][y]",
3380                                                                                                           "[y][y][0][y]", "[y][y][y][0]", "[y][y][y][y]" };
3381
3382         bool dynamic_indexing_supported = false;
3383         if (glu::contextSupports(this->context_id.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
3384                 glu::contextSupports(this->context_id.getRenderContext().getType(), glu::ApiType::core(4, 0)) ||
3385                 this->context_id.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"))
3386         {
3387                 dynamic_indexing_supported = true;
3388         }
3389
3390         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
3391         {
3392                 _supported_variable_types_map_const_iterator var_iterator =
3393                         supported_variable_types_map.find(opaque_var_types[var_type_index]);
3394
3395                 if (var_iterator != supported_variable_types_map.end())
3396                 {
3397                         int num_invalid_size_declarations =
3398                                 sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
3399
3400                         for (int invalid_size_index = 0; invalid_size_index < num_invalid_size_declarations; invalid_size_index++)
3401                         {
3402                                 std::string shader_source = "int y = 1;\n";
3403
3404                                 shader_source += "uniform " + var_iterator->second.precision + " " + var_iterator->second.type +
3405                                                                  " x[2][2][2][2];\n\n";
3406                                 shader_source += "void main()\n";
3407                                 shader_source += "{\n";
3408                                 shader_source += ("    " + var_iterator->second.type_of_result_of_texture_function +
3409                                                                   " color = texture(x" + invalid_size_declarations[invalid_size_index] + ", " +
3410                                                                   var_iterator->second.coord_param_for_texture_function + ");\n");
3411
3412                                 /* End main */
3413                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3414
3415                                 if (dynamic_indexing_supported)
3416                                 {
3417                                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, true);
3418                                 }
3419                                 else
3420                                 {
3421                                         this->execute_negative_test(tested_shader_type, shader_source);
3422                                 }
3423                         } /* for (int invalid_size_index = 0; ...) */
3424                 }        /* if var_type iterator found */
3425                 else
3426                 {
3427                         TCU_FAIL("Type not found.");
3428                 }
3429         } /* for (int var_type_index = 0; ...) */
3430 }
3431
3432 /* Generates the shader source code for the ExpressionsEquality1
3433  * array tests, and attempts to compile each test shader, for both
3434  * vertex and fragment shaders.
3435  *
3436  * @tparam API               Tested API descriptor
3437  *
3438  * @param tested_shader_type The type of shader that is being tested
3439  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3440  */
3441 template <class API>
3442 void ExpressionsEquality1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
3443 {
3444         int num_var_types = API::n_var_types;
3445
3446         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
3447         {
3448                 _supported_variable_types_map_const_iterator var_iterator =
3449                         supported_variable_types_map.find(API::var_types[var_type_index]);
3450
3451                 if (var_iterator != supported_variable_types_map.end())
3452                 {
3453                         std::string shader_source = shader_start;
3454
3455                         shader_source += "    ";
3456                         shader_source += var_iterator->second.type;
3457                         shader_source += "[][] x = ";
3458                         shader_source += var_iterator->second.type;
3459                         shader_source += "[][](";
3460                         shader_source += var_iterator->second.type;
3461                         shader_source += "[](";
3462                         shader_source += var_iterator->second.initializer_with_zeroes;
3463                         shader_source += ",";
3464                         shader_source += var_iterator->second.initializer_with_zeroes;
3465                         shader_source += "),";
3466                         shader_source += var_iterator->second.type;
3467                         shader_source += "[](";
3468                         shader_source += var_iterator->second.initializer_with_zeroes;
3469                         shader_source += ",";
3470                         shader_source += var_iterator->second.initializer_with_zeroes;
3471                         shader_source += "));\n";
3472                         shader_source += "    ";
3473                         shader_source += var_iterator->second.type;
3474                         shader_source += "[][] y = ";
3475                         shader_source += var_iterator->second.type;
3476                         shader_source += "[][](";
3477                         shader_source += var_iterator->second.type;
3478                         shader_source += "[](";
3479                         shader_source += var_iterator->second.initializer_with_zeroes;
3480                         shader_source += ",";
3481                         shader_source += var_iterator->second.initializer_with_zeroes;
3482                         shader_source += "),";
3483                         shader_source += var_iterator->second.type;
3484                         shader_source += "[](";
3485                         shader_source += var_iterator->second.initializer_with_zeroes;
3486                         shader_source += ",";
3487                         shader_source += var_iterator->second.initializer_with_zeroes;
3488                         shader_source += "));\n\n";
3489                         shader_source += "    float result = 0.0;\n\n";
3490                         shader_source += "    if (x == y)\n";
3491                         shader_source += "    {\n";
3492                         shader_source += "        result = 1.0;\n";
3493                         shader_source += "    }\n";
3494                         shader_source += "    if (y != x)\n";
3495                         shader_source += "    {\n";
3496                         shader_source += "        result = 2.0;\n";
3497                         shader_source += "    }\n";
3498
3499                         /* End main */
3500                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3501
3502                         /* Execute test */
3503                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3504                 } /* if var_type iterator found */
3505                 else
3506                 {
3507                         TCU_FAIL("Type not found.");
3508                 }
3509         }
3510 }
3511
3512 /* Generates the shader source code for the ExpressionsEquality2
3513  * array tests, and attempts to compile each test shader, for both
3514  * vertex and fragment shaders.
3515  *
3516  * @tparam API               Tested API descriptor
3517  *
3518  * @param tested_shader_type The type of shader that is being tested
3519  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3520  */
3521 template <class API>
3522 void ExpressionsEquality2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
3523 {
3524         int num_var_types = API::n_var_types;
3525
3526         for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
3527         {
3528                 _supported_variable_types_map_const_iterator var_iterator =
3529                         supported_variable_types_map.find(API::var_types[var_type_index]);
3530
3531                 if (var_iterator != supported_variable_types_map.end())
3532                 {
3533                         std::string shader_source = "struct light {\n    float intensity;\n    int position;\n};\n\n";
3534
3535                         shader_source += shader_start;
3536                         shader_source += "    light[][] x =";
3537                         shader_source += "light";
3538                         shader_source += "[][](";
3539                         shader_source += "light";
3540                         shader_source += "[](light(1.0, 1)),";
3541                         shader_source += "light";
3542                         shader_source += "[](light(2.0, 2)));\n\n";
3543                         shader_source += "    light[][] y =";
3544                         shader_source += "light";
3545                         shader_source += "[][](";
3546                         shader_source += "light";
3547                         shader_source += "[](light(3.0, 3)),";
3548                         shader_source += "light";
3549                         shader_source += "[](light(4.0, 4)));\n\n";
3550                         shader_source += "    float result = 0.0;\n\n";
3551                         shader_source += "    if (x == y)\n";
3552                         shader_source += "    {\n";
3553                         shader_source += "        result = 1.0;\n";
3554                         shader_source += "    }\n";
3555                         shader_source += "    if (y != x)\n";
3556                         shader_source += "    {\n";
3557                         shader_source += "        result = 2.0;\n";
3558                         shader_source += "    }\n";
3559
3560                         /* Apply stage specific stuff */
3561                         switch (tested_shader_type)
3562                         {
3563                         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3564                                 shader_source += "\n    gl_Position = vec4(0.0,0.0,0.0,1.0);\n";
3565                                 break;
3566                         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3567                                 shader_source += "\n    gl_FragDepth = result;\n";
3568                                 break;
3569                         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3570                                 break;
3571                         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3572                                 shader_source += emit_quad;
3573                                 break;
3574                         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
3575                                 shader_source += set_tesseation;
3576                                 break;
3577                         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3578                                 break;
3579                         default:
3580                                 TCU_FAIL("Unrecognized shader type.");
3581                                 break;
3582                         }
3583
3584                         /* End main function */
3585                         shader_source += shader_end;
3586
3587                         /* Execute test */
3588                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3589                 } /* if var_type iterator found */
3590                 else
3591                 {
3592                         TCU_FAIL("Type not found.");
3593                 }
3594         }
3595 }
3596
3597 /* Generates the shader source code for the ExpressionsLength1
3598  * array tests, and attempts to compile each test shader, for both
3599  * vertex and fragment shaders.
3600  *
3601  * @tparam API               Tested API descriptor
3602  *
3603  * @param tested_shader_type The type of shader that is being tested
3604  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3605  */
3606 template <class API>
3607 void ExpressionsLength1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
3608 {
3609         std::string array_declaration     = "    int x[4][3][2][1];\n\n";
3610         std::string case_specific_string[] = { "    if (x.length() != 4) {\n"
3611                                                                                    "        result = 0.0f;\n    }\n",
3612                                                                                    "    if (x[0].length() != 3) {\n"
3613                                                                                    "        result = 0.0f;\n    }\n",
3614                                                                                    "    if (x[0][0].length() != 2) {\n"
3615                                                                                    "        result = 0.0f;\n    }\n",
3616                                                                                    "    if (x[0][0][0].length() != 1) {\n"
3617                                                                                    "        result = 0.0f;\n    }\n" };
3618         const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
3619
3620         for (size_t case_specific_string_index = 0;
3621                  case_specific_string_index < sizeof(case_specific_string) / sizeof(case_specific_string[0]);
3622                  case_specific_string_index++)
3623         {
3624                 const std::string& test_snippet = case_specific_string[case_specific_string_index];
3625
3626                 if (false == test_compute)
3627                 {
3628                         execute_draw_test(tested_shader_type, array_declaration, test_snippet);
3629                 }
3630                 else
3631                 {
3632                         execute_dispatch_test(tested_shader_type, array_declaration, test_snippet);
3633                 }
3634
3635                 /* Deallocate any resources used. */
3636                 this->delete_objects();
3637         } /* for (int case_specific_string_index = 0; ...) */
3638 }
3639
3640 /** Executes test for compute program
3641  *
3642  * @tparam API               Tested API descriptor
3643  *
3644  * @param tested_shader_type The type of shader that is being tested
3645  * @param tested_declaration Declaration used to prepare shader
3646  * @param tested_snippet     Snippet used to prepare shader
3647  **/
3648 template <class API>
3649 void ExpressionsLength1<API>::execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
3650                                                                                                         const std::string&                                                 tested_declaration,
3651                                                                                                         const std::string&                                                 tested_snippet)
3652 {
3653         const std::string& compute_shader_source =
3654                 prepare_compute_shader(tested_shader_type, tested_declaration, tested_snippet);
3655         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
3656
3657         this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string,
3658                                                                 compute_shader_source, false, false);
3659
3660         /* We are now ready to verify whether the returned size is correct. */
3661         unsigned char buffer[4]                         = { 0 };
3662         glw::GLuint   framebuffer_object_id = 0;
3663         glw::GLint      location                                = -1;
3664         glw::GLuint   texture_object_id         = 0;
3665         glw::GLuint   vao_id                            = 0;
3666
3667         gl.useProgram(this->program_object_id);
3668         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
3669
3670         gl.genTextures(1, &texture_object_id);
3671         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
3672
3673         gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
3674         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
3675
3676         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3677         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
3678
3679         gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
3680                                                 GL_WRITE_ONLY, GL_RGBA8);
3681         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed.");
3682
3683         location = gl.getUniformLocation(this->program_object_id, "uni_image");
3684         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
3685
3686         if (-1 == location)
3687         {
3688                 TCU_FAIL("Uniform is inactive");
3689         }
3690
3691         gl.uniform1i(location, 0 /* image unit */);
3692         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
3693
3694         gl.genVertexArrays(1, &vao_id);
3695         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
3696
3697         gl.bindVertexArray(vao_id);
3698         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
3699
3700         gl.dispatchCompute(1, 1, 1);
3701         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3702
3703         gl.genFramebuffers(1, &framebuffer_object_id);
3704         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
3705
3706         gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
3707         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
3708
3709         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
3710         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
3711
3712         gl.viewport(0, 0, 1, 1);
3713         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
3714
3715         gl.readBuffer(GL_COLOR_ATTACHMENT0);
3716         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
3717
3718         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
3719         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
3720
3721         if (buffer[0] != 255)
3722         {
3723                 TCU_FAIL("Invalid array size was returned.");
3724         }
3725
3726         /* Delete generated objects. */
3727         gl.deleteTextures(1, &texture_object_id);
3728         gl.deleteFramebuffers(1, &framebuffer_object_id);
3729         gl.deleteVertexArrays(1, &vao_id);
3730         GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
3731 }
3732
3733 /** Executes test for draw program
3734  *
3735  * @tparam API               Tested API descriptor
3736  *
3737  * @param tested_shader_type The type of shader that is being tested
3738  * @param tested_declaration Declaration used to prepare shader
3739  * @param tested_snippet     Snippet used to prepare shader
3740  **/
3741 template <class API>
3742 void ExpressionsLength1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
3743                                                                                                 const std::string&                                                 tested_declaration,
3744                                                                                                 const std::string&                                                 tested_snippet)
3745 {
3746         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
3747
3748         if (API::USE_ALL_SHADER_STAGES)
3749         {
3750                 const std::string& compute_shader_source = empty_string;
3751                 const std::string& fragment_shader_source =
3752                         this->prepare_fragment_shader(tested_shader_type, tested_declaration, tested_snippet);
3753                 const std::string& geometry_shader_source =
3754                         this->prepare_geometry_shader(tested_shader_type, tested_declaration, tested_snippet);
3755                 const std::string& tess_ctrl_shader_source =
3756                         this->prepare_tess_ctrl_shader(tested_shader_type, tested_declaration, tested_snippet);
3757                 const std::string& tess_eval_shader_source =
3758                         this->prepare_tess_eval_shader(tested_shader_type, tested_declaration, tested_snippet);
3759                 const std::string& vertex_shader_source =
3760                         this->prepare_vertex_shader(tested_shader_type, tested_declaration, tested_snippet);
3761
3762                 switch (tested_shader_type)
3763                 {
3764                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
3765                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3766                         this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
3767                         break;
3768
3769                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3770                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3771                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
3772                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3773                         this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
3774                                                                                 geometry_shader_source, fragment_shader_source, compute_shader_source, false,
3775                                                                                 false);
3776                         break;
3777
3778                 default:
3779                         TCU_FAIL("Invalid enum");
3780                         break;
3781                 }
3782         }
3783         else
3784         {
3785                 const std::string& fragment_shader_source =
3786                         this->prepare_fragment_shader(tested_shader_type, tested_declaration, tested_snippet);
3787                 const std::string& vertex_shader_source =
3788                         this->prepare_vertex_shader(tested_shader_type, tested_declaration, tested_snippet);
3789
3790                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
3791         }
3792
3793         /* We are now ready to verify whether the returned size is correct. */
3794         unsigned char buffer[4]                         = { 0 };
3795         glw::GLuint   framebuffer_object_id = 0;
3796         glw::GLuint   texture_object_id         = 0;
3797         glw::GLuint   vao_id                            = 0;
3798
3799         gl.useProgram(this->program_object_id);
3800         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
3801
3802         gl.genTextures(1, &texture_object_id);
3803         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
3804
3805         gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
3806         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
3807
3808         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3809         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
3810
3811         gl.genFramebuffers(1, &framebuffer_object_id);
3812         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
3813
3814         gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
3815         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
3816
3817         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
3818         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
3819
3820         gl.viewport(0, 0, 1, 1);
3821         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
3822
3823         gl.genVertexArrays(1, &vao_id);
3824         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
3825
3826         gl.bindVertexArray(vao_id);
3827         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
3828
3829         switch (tested_shader_type)
3830         {
3831         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
3832         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3833                 gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
3834                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3835                 break;
3836
3837         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
3838         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3839                 /* Tesselation patch set up */
3840                 gl.patchParameteri(GL_PATCH_VERTICES, 1);
3841                 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
3842
3843                 gl.drawArrays(GL_PATCHES, 0, 1);
3844                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3845                 break;
3846
3847         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3848                 gl.drawArrays(GL_POINTS, 0, 1);
3849                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3850                 break;
3851
3852         default:
3853                 TCU_FAIL("Invalid enum");
3854                 break;
3855         }
3856
3857         gl.readBuffer(GL_COLOR_ATTACHMENT0);
3858         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
3859
3860         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
3861         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
3862
3863         if (buffer[0] != 255)
3864         {
3865                 TCU_FAIL("Invalid array size was returned.");
3866         }
3867
3868         /* Delete generated objects. */
3869         gl.deleteTextures(1, &texture_object_id);
3870         gl.deleteFramebuffers(1, &framebuffer_object_id);
3871         gl.deleteVertexArrays(1, &vao_id);
3872         GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
3873 }
3874
3875 /** Prepare shader
3876  *
3877  * @tparam API               Tested API descriptor
3878  *
3879  * @param tested_shader_type The type of shader that is being tested
3880  * @param tested_declaration Declaration used to prepare shader
3881  * @param tested_snippet     Snippet used to prepare shader
3882  **/
3883 template <class API>
3884 std::string ExpressionsLength1<API>::prepare_compute_shader(
3885         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
3886         const std::string& tested_snippet)
3887 {
3888         std::string compute_shader_source;
3889
3890         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
3891         {
3892                 compute_shader_source = "writeonly uniform image2D uni_image;\n"
3893                                                                 "\n"
3894                                                                 "void main()\n"
3895                                                                 "{\n"
3896                                                                 "    float result = 1u;\n"
3897                                                                 "\n";
3898                 compute_shader_source += tested_declaration;
3899                 compute_shader_source += tested_snippet;
3900                 compute_shader_source += "\n"
3901                                                                  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
3902                                                                  "}\n"
3903                                                                  "\n";
3904         }
3905
3906         return compute_shader_source;
3907 }
3908
3909 /** Prepare shader
3910  *
3911  * @tparam API               Tested API descriptor
3912  *
3913  * @param tested_shader_type The type of shader that is being tested
3914  * @param tested_declaration Declaration used to prepare shader
3915  * @param tested_snippet     Snippet used to prepare shader
3916  **/
3917 template <class API>
3918 std::string ExpressionsLength1<API>::prepare_fragment_shader(
3919         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
3920         const std::string& tested_snippet)
3921 {
3922         std::string fragment_shader_source;
3923
3924         switch (tested_shader_type)
3925         {
3926         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3927                 break;
3928
3929         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3930                 fragment_shader_source = "out vec4 colour;\n"
3931                                                                  "\n"
3932                                                                  "void main()\n"
3933                                                                  "{\n";
3934                 fragment_shader_source += tested_declaration;
3935                 fragment_shader_source += "    float result = 1.0f;\n";
3936                 fragment_shader_source += tested_snippet;
3937                 fragment_shader_source += "    colour = vec4(result);\n"
3938                                                                   "}\n\n";
3939                 break;
3940
3941         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3942         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
3943         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3944         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3945                 fragment_shader_source = "in float fs_result;\n\n"
3946                                                                  "out vec4 colour;\n\n"
3947                                                                  "void main()\n"
3948                                                                  "{\n"
3949                                                                  "    colour =  vec4(fs_result);\n"
3950                                                                  "}\n"
3951                                                                  "\n";
3952                 break;
3953
3954         default:
3955                 TCU_FAIL("Unrecognized shader object type.");
3956                 break;
3957         }
3958
3959         return fragment_shader_source;
3960 }
3961
3962 /** Prepare shader
3963  *
3964  * @tparam API               Tested API descriptor
3965  *
3966  * @param tested_shader_type The type of shader that is being tested
3967  * @param tested_declaration Declaration used to prepare shader
3968  * @param tested_snippet     Snippet used to prepare shader
3969  **/
3970 template <class API>
3971 std::string ExpressionsLength1<API>::prepare_geometry_shader(
3972         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
3973         const std::string& tested_snippet)
3974 {
3975         std::string geometry_shader_source;
3976
3977         switch (tested_shader_type)
3978         {
3979         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3980         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3981         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3982                 break;
3983
3984         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
3985         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3986                 geometry_shader_source = "layout(points)                           in;\n"
3987                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
3988                                                                  "\n"
3989                                                                  "in  float tes_result[];\n"
3990                                                                  "out float fs_result;\n"
3991                                                                  "\n"
3992                                                                  "void main()\n"
3993                                                                  "{\n"
3994                                                                  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
3995                                                                  "    fs_result    = tes_result[0];\n"
3996                                                                  "    EmitVertex();\n"
3997                                                                  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
3998                                                                  "    fs_result    = tes_result[0];\n"
3999                                                                  "    EmitVertex();\n"
4000                                                                  "    gl_Position  = vec4(1, -1, 0, 1);\n"
4001                                                                  "    fs_result    = tes_result[0];\n"
4002                                                                  "    EmitVertex();\n"
4003                                                                  "    gl_Position  = vec4(1, 1, 0, 1);\n"
4004                                                                  "    fs_result    = tes_result[0];\n"
4005                                                                  "    EmitVertex();\n"
4006                                                                  "}\n";
4007                 break;
4008
4009         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4010                 geometry_shader_source = "layout(points)                           in;\n"
4011                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
4012                                                                  "\n"
4013                                                                  "out float fs_result;\n"
4014                                                                  "\n"
4015                                                                  "void main()\n"
4016                                                                  "{\n";
4017                 geometry_shader_source += tested_declaration;
4018                 geometry_shader_source += "    float result = 1.0;\n\n";
4019                 geometry_shader_source += tested_snippet;
4020                 geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
4021                                                                   "    fs_result    = result;\n"
4022                                                                   "    EmitVertex();\n"
4023                                                                   "    gl_Position  = vec4(-1, 1, 0, 1);\n"
4024                                                                   "    fs_result    = result;\n"
4025                                                                   "    EmitVertex();\n"
4026                                                                   "    gl_Position  = vec4(1, -1, 0, 1);\n"
4027                                                                   "    fs_result    = result;\n"
4028                                                                   "    EmitVertex();\n"
4029                                                                   "    gl_Position  = vec4(1, 1, 0, 1);\n"
4030                                                                   "    fs_result    = result;\n"
4031                                                                   "    EmitVertex();\n"
4032                                                                   "}\n";
4033                 break;
4034
4035         default:
4036                 TCU_FAIL("Unrecognized shader object type.");
4037                 break;
4038         }
4039
4040         return geometry_shader_source;
4041 }
4042
4043 /** Prepare shader
4044  *
4045  * @tparam API               Tested API descriptor
4046  *
4047  * @param tested_shader_type The type of shader that is being tested
4048  * @param tested_declaration Declaration used to prepare shader
4049  * @param tested_snippet     Snippet used to prepare shader
4050  **/
4051 template <class API>
4052 std::string ExpressionsLength1<API>::prepare_tess_ctrl_shader(
4053         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
4054         const std::string& tested_snippet)
4055 {
4056         std::string tess_ctrl_shader_source;
4057
4058         switch (tested_shader_type)
4059         {
4060         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4061         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4062         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4063         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4064                 break;
4065
4066         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4067                 tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
4068                                                                   "\n"
4069                                                                   "out float tcs_result[];\n"
4070                                                                   "\n"
4071                                                                   "void main()\n"
4072                                                                   "{\n";
4073                 tess_ctrl_shader_source += tested_declaration;
4074                 tess_ctrl_shader_source += "    float result = 1.0;\n\n";
4075                 tess_ctrl_shader_source += tested_snippet;
4076                 tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
4077                                                                    "\n"
4078                                                                    "    gl_TessLevelOuter[0] = 1.0;\n"
4079                                                                    "    gl_TessLevelOuter[1] = 1.0;\n"
4080                                                                    "    gl_TessLevelOuter[2] = 1.0;\n"
4081                                                                    "    gl_TessLevelOuter[3] = 1.0;\n"
4082                                                                    "    gl_TessLevelInner[0] = 1.0;\n"
4083                                                                    "    gl_TessLevelInner[1] = 1.0;\n"
4084                                                                    "}\n";
4085                 break;
4086
4087         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4088                 tess_ctrl_shader_source = default_tc_shader_source;
4089                 break;
4090
4091         default:
4092                 TCU_FAIL("Unrecognized shader object type.");
4093                 break;
4094         }
4095
4096         return tess_ctrl_shader_source;
4097 }
4098
4099 /** Prepare shader
4100  *
4101  * @tparam API               Tested API descriptor
4102  *
4103  * @param tested_shader_type The type of shader that is being tested
4104  * @param tested_declaration Declaration used to prepare shader
4105  * @param tested_snippet     Snippet used to prepare shader
4106  **/
4107 template <class API>
4108 std::string ExpressionsLength1<API>::prepare_tess_eval_shader(
4109         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
4110         const std::string& tested_snippet)
4111 {
4112         std::string tess_eval_shader_source;
4113
4114         switch (tested_shader_type)
4115         {
4116         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4117         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4118         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4119         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4120                 break;
4121
4122         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4123                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
4124                                                                   "\n"
4125                                                                   "in  float tcs_result[];\n"
4126                                                                   "out float tes_result;\n"
4127                                                                   "\n"
4128                                                                   "void main()\n"
4129                                                                   "{\n"
4130                                                                   "    tes_result = tcs_result[0];\n"
4131                                                                   "}\n";
4132                 break;
4133
4134         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4135                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
4136                                                                   "\n"
4137                                                                   "out float tes_result;\n"
4138                                                                   "\n"
4139                                                                   "void main()\n"
4140                                                                   "{\n";
4141                 tess_eval_shader_source += tested_declaration;
4142                 tess_eval_shader_source += "    float result = 1.0;\n\n";
4143                 tess_eval_shader_source += tested_snippet;
4144                 tess_eval_shader_source += "    tes_result = result;\n"
4145                                                                    "}\n";
4146                 break;
4147
4148         default:
4149                 TCU_FAIL("Unrecognized shader object type.");
4150                 break;
4151         }
4152
4153         return tess_eval_shader_source;
4154 }
4155
4156 /** Prepare shader
4157  *
4158  * @tparam API               Tested API descriptor
4159  *
4160  * @param tested_shader_type The type of shader that is being tested
4161  * @param tested_declaration Declaration used to prepare shader
4162  * @param tested_snippet     Snippet used to prepare shader
4163  **/
4164 template <class API>
4165 std::string ExpressionsLength1<API>::prepare_vertex_shader(
4166         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
4167         const std::string& tested_snippet)
4168 {
4169         std::string vertex_shader_source;
4170
4171         switch (tested_shader_type)
4172         {
4173         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4174                 break;
4175
4176         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4177                 vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
4178                                                            "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
4179                                                            "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
4180                                                            "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
4181                                                            "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
4182                                                            "\n"
4183                                                            "void main()\n"
4184                                                            "{\n"
4185                                                            "    gl_Position = vertex_positions[gl_VertexID];"
4186                                                            "}\n\n";
4187                 break;
4188
4189         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4190         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4191         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4192                 vertex_shader_source = default_vertex_shader_source;
4193                 break;
4194
4195         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4196                 vertex_shader_source = "out float fs_result;\n"
4197                                                            "\n"
4198                                                            "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
4199                                                            "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
4200                                                            "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
4201                                                            "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
4202                                                            "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
4203                                                            "\n"
4204                                                            "void main()\n"
4205                                                            "{\n";
4206                 vertex_shader_source += tested_declaration;
4207                 vertex_shader_source += "    float result = 1.0;\n\n";
4208                 vertex_shader_source += tested_snippet;
4209                 vertex_shader_source += "    gl_Position = vertex_positions[gl_VertexID];\n"
4210                                                                 "    fs_result = result;\n";
4211                 vertex_shader_source += shader_end;
4212                 break;
4213
4214         default:
4215                 TCU_FAIL("Unrecognized shader object type.");
4216                 break;
4217         }
4218
4219         return vertex_shader_source;
4220 }
4221
4222 /* Generates the shader source code for the ExpressionsLength2
4223  * array tests, and attempts to compile each test shader, for both
4224  * vertex and fragment shaders.
4225  *
4226  * @tparam API               Tested API descriptor
4227  *
4228  * @param tested_shader_type The type of shader that is being tested
4229  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4230  */
4231 template <class API>
4232 void ExpressionsLength2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4233 {
4234         std::string array_declaration     = "    int x[1][2][3][4];\n\n";
4235         std::string case_specific_string[] = { "    if (x.length() != 1) {\n"
4236                                                                                    "        result = 0.0f;\n    }\n",
4237                                                                                    "    if (x[0].length() != 2) {\n"
4238                                                                                    "        result = 0.0f;\n    }\n",
4239                                                                                    "    if (x[0][0].length() != 3) {\n"
4240                                                                                    "        result = 0.0f;\n    }\n",
4241                                                                                    "    if (x[0][0][0].length() != 4) {\n"
4242                                                                                    "        result = 0.0f;\n    }\n" };
4243         const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
4244
4245         for (size_t case_specific_string_index = 0;
4246                  case_specific_string_index < sizeof(case_specific_string) / sizeof(case_specific_string[0]);
4247                  case_specific_string_index++)
4248         {
4249                 const std::string& test_snippet = case_specific_string[case_specific_string_index];
4250
4251                 if (false == test_compute)
4252                 {
4253                         this->execute_draw_test(tested_shader_type, array_declaration, test_snippet);
4254                 }
4255                 else
4256                 {
4257                         this->execute_dispatch_test(tested_shader_type, array_declaration, test_snippet);
4258                 }
4259
4260                 /* Deallocate any resources used. */
4261                 this->delete_objects();
4262         } /* for (int case_specific_string_index = 0; ...) */
4263 }
4264
4265 /* Generates the shader source code for the ExpressionsLength3
4266  * array tests, and attempts to compile each test shader, for both
4267  * vertex and fragment shaders.
4268  *
4269  * @tparam API               Tested API descriptor
4270  *
4271  * @param tested_shader_type The type of shader that is being tested
4272  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4273  */
4274 template <class API>
4275 void ExpressionsLength3<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4276 {
4277         std::string array_declaration = "    int x[1][1][1][1];\n\n";
4278         std::string input[]                       = { "    if (x[].length() != 2) {\n"
4279                                                         "        result = 0.0f;\n    }\n",
4280                                                         "    if (x[][].length() != 2)  {\n"
4281                                                         "        result = 0.0f;\n    }\n",
4282                                                         "    if (x[][][].length() != 2)  {\n"
4283                                                         "        result = 0.0f;\n    }\n" };
4284
4285         for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
4286         {
4287                 std::string                shader_source;
4288                 const std::string& test_snippet = input[string_index];
4289
4290                 switch (tested_shader_type)
4291                 {
4292                 case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4293                         shader_source = this->prepare_vertex_shader(tested_shader_type, array_declaration, test_snippet);
4294                         break;
4295
4296                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4297                         shader_source = this->prepare_fragment_shader(tested_shader_type, array_declaration, test_snippet);
4298                         break;
4299
4300                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4301                         shader_source = this->prepare_compute_shader(tested_shader_type, array_declaration, test_snippet);
4302                         break;
4303
4304                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4305                         shader_source = this->prepare_geometry_shader(tested_shader_type, array_declaration, test_snippet);
4306                         break;
4307
4308                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4309                         shader_source = this->prepare_tess_ctrl_shader(tested_shader_type, array_declaration, test_snippet);
4310                         break;
4311
4312                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4313                         shader_source = this->prepare_tess_eval_shader(tested_shader_type, array_declaration, test_snippet);
4314                         break;
4315
4316                 default:
4317                         TCU_FAIL("Unrecognized shader type.");
4318                         break;
4319                 } /* switch (tested_shader_type) */
4320
4321                 this->execute_negative_test(tested_shader_type, shader_source);
4322         } /* for (int string_index = 0; ...) */
4323 }
4324
4325 /* Generates the shader source code for the ExpressionsInvalid1
4326  * array tests, and attempts to compile each test shader, for both
4327  * vertex and fragment shaders.
4328  *
4329  * @tparam API               Tested API descriptor
4330  *
4331  * @param tested_shader_type The type of shader that is being tested
4332  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4333  */
4334 template <class API>
4335 void ExpressionsInvalid1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4336 {
4337         std::string shader_variable_declarations =
4338                 "    mat2  y       = mat2(0.0);\n"
4339                 "    float x[2][2] = float[2][2](float[2](4.0, 5.0), float[2](6.0, 7.0));\n\n";
4340
4341         std::string shader_source = shader_start + shader_variable_declarations;
4342
4343         shader_source += "    y = x;\n";
4344
4345         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
4346
4347         this->execute_negative_test(tested_shader_type, shader_source);
4348 }
4349
4350 /* Generates the shader source code for the ExpressionsInvalid2
4351  * array tests, and attempts to compile each test shader, for both
4352  * vertex and fragment shaders.
4353  *
4354  * @tparam API               Tested API descriptor
4355  *
4356  * @param tested_shader_type The type of shader that is being tested
4357  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4358  */
4359 template <class API>
4360 void ExpressionsInvalid2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4361 {
4362
4363         std::string shader_variable_declarations[] = { " x", " y" };
4364         std::string variable_relation_opeartors[]  = {
4365                 "    float result = 0.0;\n\n    if(x < y)\n    {\n        result = 1.0;\n    }\n\n\n",
4366                 "    float result = 0.0;\n\n    if(x <= y)\n    {\n        result = 1.0;\n    }\n\n\n",
4367                 "    float result = 0.0;\n\n    if(x > y)\n    {\n        result = 1.0;\n    }\n\n\n",
4368                 "    float result = 0.0;\n\n    if(x >= y)\n    {\n        result = 1.0;\n    }\n\n\n"
4369         };
4370         std::string valid_relation_opeartors =
4371                 "    float result = 0.0;\n\n    if(x == y)\n    {\n        result = 1.0;\n    }\n\n\n";
4372
4373         for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
4374         {
4375                 _supported_variable_types_map_const_iterator var_iterator =
4376                         supported_variable_types_map.find(API::var_types[var_type_index]);
4377
4378                 if (var_iterator != supported_variable_types_map.end())
4379                 {
4380                         std::string base_variable_string;
4381
4382                         for (size_t variable_declaration_index = 0;
4383                                  variable_declaration_index <
4384                                  sizeof(shader_variable_declarations) / sizeof(shader_variable_declarations[0]);
4385                                  variable_declaration_index++)
4386                         {
4387                                 base_variable_string += var_iterator->second.type;
4388                                 base_variable_string += shader_variable_declarations[variable_declaration_index];
4389
4390                                 base_variable_string += "[1][1][1][1][1][1][1][1] = ";
4391
4392                                 for (size_t sub_script_index = 0; sub_script_index < API::MAX_ARRAY_DIMENSIONS; sub_script_index++)
4393                                 {
4394                                         base_variable_string += this->extend_string(var_iterator->second.type, "[1]",
4395                                                                                                                                 API::MAX_ARRAY_DIMENSIONS - sub_script_index);
4396                                         base_variable_string += "(";
4397                                 }
4398
4399                                 base_variable_string += var_iterator->second.initializer_with_ones;
4400
4401                                 for (size_t sub_script_index = 0; sub_script_index < API::MAX_ARRAY_DIMENSIONS; sub_script_index++)
4402                                 {
4403                                         base_variable_string += ")";
4404                                 }
4405
4406                                 base_variable_string += ";\n";
4407                         } /* for (int variable_declaration_index = 0; ...) */
4408
4409                         /* Run positive case */
4410                         {
4411                                 std::string shader_source;
4412
4413                                 shader_source = base_variable_string + "\n";
4414                                 shader_source += shader_start + valid_relation_opeartors;
4415
4416                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
4417
4418                                 EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
4419                         }
4420
4421                         /* Run negative cases */
4422                         for (size_t string_index = 0;
4423                                  string_index < sizeof(variable_relation_opeartors) / sizeof(variable_relation_opeartors[0]);
4424                                  string_index++)
4425                         {
4426                                 std::string shader_source;
4427
4428                                 shader_source = base_variable_string + "\n";
4429                                 shader_source += shader_start + variable_relation_opeartors[string_index];
4430
4431                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
4432
4433                                 this->execute_negative_test(tested_shader_type, shader_source);
4434                         } /* for (int string_index = 0; ...) */
4435                 }        /* if var_type iterator found */
4436                 else
4437                 {
4438                         TCU_FAIL("Type not found.");
4439                 }
4440         } /* for (int var_type_index = 0; ...) */
4441 }
4442
4443 /* Generates the shader source code for the InteractionFunctionCalls1
4444  * array tests, and attempts to compile each test shader, for both
4445  * vertex and fragment shaders.
4446  *
4447  * @tparam API               Tested API descriptor
4448  *
4449  * @param tested_shader_type The type of shader that is being tested
4450  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4451  */
4452 template <class API>
4453 void InteractionFunctionCalls1<API>::test_shader_compilation(
4454         typename TestCaseBase<API>::TestShaderType tested_shader_type)
4455 {
4456         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
4457                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
4458                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
4459                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
4460         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
4461
4462         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
4463                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
4464                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
4465                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
4466                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
4467         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
4468
4469         const std::string iteration_loop_end = "                }\n"
4470                                                                                    "            }\n"
4471                                                                                    "        }\n"
4472                                                                                    "    }\n";
4473         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
4474                                                                                          "    {\n"
4475                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
4476                                                                                          "        {\n"
4477                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
4478                                                                                          "            {\n"
4479                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
4480                                                                                          "                {\n";
4481         const glcts::test_var_type* var_types_set = var_types_set_es;
4482         size_t                                          num_var_types = num_var_types_es;
4483         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
4484
4485         if (API::USE_DOUBLE)
4486         {
4487                 var_types_set = var_types_set_gl;
4488                 num_var_types = num_var_types_gl;
4489         }
4490
4491         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
4492         {
4493                 _supported_variable_types_map_const_iterator var_iterator =
4494                         supported_variable_types_map.find(var_types_set[var_type_index]);
4495
4496                 if (var_iterator != supported_variable_types_map.end())
4497                 {
4498                         std::string iterator_declaration = "    " + var_iterator->second.iterator_type +
4499                                                                                            " iterator = " + var_iterator->second.iterator_initialization + ";\n";
4500
4501                         std::string function_definition;
4502                         std::string function_use;
4503                         std::string verification;
4504
4505                         function_definition = "void my_function(out ";
4506                         function_definition += var_iterator->second.type;
4507                         function_definition += " output_array[2][2][2][2]) {\n";
4508                         function_definition += iterator_declaration;
4509                         function_definition += iteration_loop_start;
4510                         function_definition += "                                   output_array[a][b][c][d] = " +
4511                                                                    var_iterator->second.variable_type_initializer1 + ";\n";
4512                         function_definition +=
4513                                 "                                   iterator += " + var_iterator->second.iterator_type + "(1);\n";
4514                         function_definition += iteration_loop_end;
4515                         function_definition += "}";
4516
4517                         function_use = "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
4518                         function_use += "    my_function(my_array);";
4519
4520                         verification = iterator_declaration;
4521                         verification += "    float result = 1.0;\n";
4522                         verification += iteration_loop_start;
4523                         verification += "                                   if (my_array[a][b][c][d] " +
4524                                                         var_iterator->second.specific_element +
4525                                                         " != iterator)\n"
4526                                                         "                                   {\n"
4527                                                         "                                       result = 0.0;\n"
4528                                                         "                                   }\n"
4529                                                         "                                   iterator += " +
4530                                                         var_iterator->second.iterator_type + "(1);\n";
4531                         verification += iteration_loop_end;
4532
4533                         if (false == test_compute)
4534                         {
4535                                 execute_draw_test(tested_shader_type, function_definition, function_use, verification);
4536                         }
4537                         else
4538                         {
4539                                 execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
4540                         }
4541
4542                         /* Deallocate any resources used. */
4543                         this->delete_objects();
4544                 } /* if var_type iterator found */
4545                 else
4546                 {
4547                         TCU_FAIL("Type not found.");
4548                 }
4549         } /* for (int var_type_index = 0; ...) */
4550 }
4551
4552 /** Executes test for compute program
4553  *
4554  * @tparam API                Tested API descriptor
4555  *
4556  * @param tested_shader_type  The type of shader that is being tested
4557  * @param function_definition Definition used to prepare shader
4558  * @param function_use        Snippet that makes use of defined function
4559  * @param verification        Snippet that verifies results
4560  **/
4561 template <class API>
4562 void InteractionFunctionCalls1<API>::execute_dispatch_test(
4563         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4564         const std::string& function_use, const std::string& verification)
4565 {
4566         const std::string& compute_shader_source =
4567                 prepare_compute_shader(tested_shader_type, function_definition, function_use, verification);
4568         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
4569
4570         this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string,
4571                                                                 compute_shader_source, false, false);
4572
4573         /* We are now ready to verify whether the returned size is correct. */
4574         unsigned char buffer[4]                         = { 0 };
4575         glw::GLuint   framebuffer_object_id = 0;
4576         glw::GLint      location                                = -1;
4577         glw::GLuint   texture_object_id         = 0;
4578         glw::GLuint   vao_id                            = 0;
4579
4580         gl.useProgram(this->program_object_id);
4581         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
4582
4583         gl.genTextures(1, &texture_object_id);
4584         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
4585
4586         gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
4587         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
4588
4589         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
4590         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
4591
4592         gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
4593                                                 GL_WRITE_ONLY, GL_RGBA8);
4594         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed.");
4595
4596         location = gl.getUniformLocation(this->program_object_id, "uni_image");
4597         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
4598
4599         if (-1 == location)
4600         {
4601                 TCU_FAIL("Uniform is inactive");
4602         }
4603
4604         gl.uniform1i(location, 0 /* image unit */);
4605         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
4606
4607         gl.genVertexArrays(1, &vao_id);
4608         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
4609
4610         gl.bindVertexArray(vao_id);
4611         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
4612
4613         gl.dispatchCompute(1, 1, 1);
4614         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4615
4616         gl.genFramebuffers(1, &framebuffer_object_id);
4617         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
4618
4619         gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
4620         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
4621
4622         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
4623         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
4624
4625         gl.viewport(0, 0, 1, 1);
4626         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
4627
4628         gl.readBuffer(GL_COLOR_ATTACHMENT0);
4629         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
4630
4631         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
4632         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
4633
4634         if (buffer[0] != 255)
4635         {
4636                 TCU_FAIL("Invalid array size was returned.");
4637         }
4638
4639         /* Delete generated objects. */
4640         gl.deleteTextures(1, &texture_object_id);
4641         gl.deleteFramebuffers(1, &framebuffer_object_id);
4642         gl.deleteVertexArrays(1, &vao_id);
4643         GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
4644 }
4645
4646 /** Executes test for draw program
4647  *
4648  * @tparam API                Tested API descriptor
4649  *
4650  * @param tested_shader_type  The type of shader that is being tested
4651  * @param function_definition Definition used to prepare shader
4652  * @param function_use        Snippet that makes use of defined function
4653  * @param verification        Snippet that verifies results
4654  **/
4655 template <class API>
4656 void InteractionFunctionCalls1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
4657                                                                                                            const std::string&                                             function_definition,
4658                                                                                                            const std::string& function_use, const std::string& verification)
4659 {
4660         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
4661
4662         if (API::USE_ALL_SHADER_STAGES)
4663         {
4664                 const std::string& compute_shader_source = empty_string;
4665                 const std::string& fragment_shader_source =
4666                         this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
4667                 const std::string& geometry_shader_source =
4668                         this->prepare_geometry_shader(tested_shader_type, function_definition, function_use, verification);
4669                 const std::string& tess_ctrl_shader_source =
4670                         this->prepare_tess_ctrl_shader(tested_shader_type, function_definition, function_use, verification);
4671                 const std::string& tess_eval_shader_source =
4672                         this->prepare_tess_eval_shader(tested_shader_type, function_definition, function_use, verification);
4673                 const std::string& vertex_shader_source =
4674                         this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
4675
4676                 switch (tested_shader_type)
4677                 {
4678                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
4679                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4680                         this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
4681                         break;
4682
4683                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4684                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4685                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
4686                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4687                         this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
4688                                                                                 geometry_shader_source, fragment_shader_source, compute_shader_source, false,
4689                                                                                 false);
4690                         break;
4691
4692                 default:
4693                         TCU_FAIL("Invalid enum");
4694                         break;
4695                 }
4696         }
4697         else
4698         {
4699                 const std::string& fragment_shader_source =
4700                         this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
4701                 const std::string& vertex_shader_source =
4702                         this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
4703
4704                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
4705         }
4706
4707         /* We are now ready to verify whether the returned size is correct. */
4708         unsigned char buffer[4]                         = { 0 };
4709         glw::GLuint   framebuffer_object_id = 0;
4710         glw::GLuint   texture_object_id         = 0;
4711         glw::GLuint   vao_id                            = 0;
4712
4713         gl.useProgram(this->program_object_id);
4714         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
4715
4716         gl.genTextures(1, &texture_object_id);
4717         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
4718
4719         gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
4720         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
4721
4722         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
4723         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
4724
4725         gl.genFramebuffers(1, &framebuffer_object_id);
4726         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
4727
4728         gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
4729         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
4730
4731         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
4732         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
4733
4734         gl.viewport(0, 0, 1, 1);
4735         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
4736
4737         gl.genVertexArrays(1, &vao_id);
4738         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
4739
4740         gl.bindVertexArray(vao_id);
4741         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
4742
4743         switch (tested_shader_type)
4744         {
4745         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
4746         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4747                 gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
4748                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4749                 break;
4750
4751         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
4752         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4753                 /* Tesselation patch set up */
4754                 gl.patchParameteri(GL_PATCH_VERTICES, 1);
4755                 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
4756
4757                 gl.drawArrays(GL_PATCHES, 0, 1);
4758                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4759                 break;
4760
4761         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4762                 gl.drawArrays(GL_POINTS, 0, 1);
4763                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4764                 break;
4765
4766         default:
4767                 TCU_FAIL("Invalid enum");
4768                 break;
4769         }
4770
4771         gl.readBuffer(GL_COLOR_ATTACHMENT0);
4772         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
4773
4774         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
4775         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
4776
4777         if (buffer[0] != 255)
4778         {
4779                 TCU_FAIL("Invalid array size was returned.");
4780         }
4781
4782         /* Delete generated objects. */
4783         gl.bindTexture(GL_TEXTURE_2D, 0);
4784         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4785         gl.bindVertexArray(0);
4786         gl.deleteTextures(1, &texture_object_id);
4787         gl.deleteFramebuffers(1, &framebuffer_object_id);
4788         gl.deleteVertexArrays(1, &vao_id);
4789         GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
4790 }
4791
4792 /** Prepare shader
4793  *
4794  * @tparam API                Tested API descriptor
4795  *
4796  * @param tested_shader_type  The type of shader that is being tested
4797  * @param function_definition Definition used to prepare shader
4798  * @param function_use        Snippet that makes use of defined function
4799  * @param verification        Snippet that verifies results
4800  **/
4801 template <class API>
4802 std::string InteractionFunctionCalls1<API>::prepare_compute_shader(
4803         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4804         const std::string& function_use, const std::string& verification)
4805 {
4806         std::string compute_shader_source;
4807
4808         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
4809         {
4810                 compute_shader_source = "writeonly uniform image2D uni_image;\n"
4811                                                                 "\n";
4812
4813                 /* User-defined function definition. */
4814                 compute_shader_source += function_definition;
4815                 compute_shader_source += "\n\n";
4816
4817                 /* Main function definition. */
4818                 compute_shader_source += shader_start;
4819                 compute_shader_source += function_use;
4820                 compute_shader_source += "\n\n";
4821                 compute_shader_source += verification;
4822                 compute_shader_source += "\n\n";
4823                 compute_shader_source += "\n"
4824                                                                  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
4825                                                                  "}\n"
4826                                                                  "\n";
4827         }
4828
4829         return compute_shader_source;
4830 }
4831
4832 /** Prepare shader
4833  *
4834  * @tparam API                Tested API descriptor
4835  *
4836  * @param tested_shader_type  The type of shader that is being tested
4837  * @param function_definition Definition used to prepare shader
4838  * @param function_use        Snippet that makes use of defined function
4839  * @param verification        Snippet that verifies results
4840  **/
4841 template <class API>
4842 std::string InteractionFunctionCalls1<API>::prepare_fragment_shader(
4843         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4844         const std::string& function_use, const std::string& verification)
4845 {
4846         std::string fragment_shader_source;
4847
4848         switch (tested_shader_type)
4849         {
4850         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4851                 break;
4852
4853         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4854                 fragment_shader_source = "out vec4 colour;\n\n";
4855
4856                 /* User-defined function definition. */
4857                 fragment_shader_source += function_definition;
4858                 fragment_shader_source += "\n\n";
4859
4860                 /* Main function definition. */
4861                 fragment_shader_source += shader_start;
4862                 fragment_shader_source += function_use;
4863                 fragment_shader_source += "\n\n";
4864                 fragment_shader_source += verification;
4865                 fragment_shader_source += "\n\n";
4866                 fragment_shader_source += "    colour = vec4(result);\n";
4867                 fragment_shader_source += shader_end;
4868                 break;
4869
4870         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4871         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4872         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4873         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4874                 fragment_shader_source = "in float fs_result;\n\n"
4875                                                                  "out vec4 colour;\n\n"
4876                                                                  "void main()\n"
4877                                                                  "{\n"
4878                                                                  "    colour =  vec4(fs_result);\n"
4879                                                                  "}\n"
4880                                                                  "\n";
4881                 break;
4882
4883         default:
4884                 TCU_FAIL("Unrecognized shader object type.");
4885                 break;
4886         }
4887
4888         return fragment_shader_source;
4889 }
4890
4891 /** Prepare shader
4892  *
4893  * @tparam API                Tested API descriptor
4894  *
4895  * @param tested_shader_type  The type of shader that is being tested
4896  * @param function_definition Definition used to prepare shader
4897  * @param function_use        Snippet that makes use of defined function
4898  * @param verification        Snippet that verifies results
4899  **/
4900 template <class API>
4901 std::string InteractionFunctionCalls1<API>::prepare_geometry_shader(
4902         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4903         const std::string& function_use, const std::string& verification)
4904 {
4905         std::string geometry_shader_source;
4906
4907         switch (tested_shader_type)
4908         {
4909         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4910         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4911         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4912                 break;
4913
4914         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4915         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4916                 geometry_shader_source = "layout(points)                           in;\n"
4917                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
4918                                                                  "\n"
4919                                                                  "in  float tes_result[];\n"
4920                                                                  "out float fs_result;\n"
4921                                                                  "\n"
4922                                                                  "void main()\n"
4923                                                                  "{\n"
4924                                                                  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
4925                                                                  "    fs_result    = tes_result[0];\n"
4926                                                                  "    EmitVertex();\n"
4927                                                                  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
4928                                                                  "    fs_result    = tes_result[0];\n"
4929                                                                  "    EmitVertex();\n"
4930                                                                  "    gl_Position  = vec4(1, -1, 0, 1);\n"
4931                                                                  "    fs_result    = tes_result[0];\n"
4932                                                                  "    EmitVertex();\n"
4933                                                                  "    gl_Position  = vec4(1, 1, 0, 1);\n"
4934                                                                  "    fs_result    = tes_result[0];\n"
4935                                                                  "    EmitVertex();\n"
4936                                                                  "}\n";
4937                 break;
4938
4939         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4940                 geometry_shader_source = "layout(points)                           in;\n"
4941                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
4942                                                                  "\n"
4943                                                                  "out float fs_result;\n"
4944                                                                  "\n";
4945
4946                 /* User-defined function definition. */
4947                 geometry_shader_source += function_definition;
4948                 geometry_shader_source += "\n\n";
4949
4950                 /* Main function definition. */
4951                 geometry_shader_source += shader_start;
4952                 geometry_shader_source += function_use;
4953                 geometry_shader_source += "\n\n";
4954                 geometry_shader_source += verification;
4955                 geometry_shader_source += "\n\n";
4956                 geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
4957                                                                   "    fs_result    = result;\n"
4958                                                                   "    EmitVertex();\n"
4959                                                                   "    gl_Position  = vec4(-1, 1, 0, 1);\n"
4960                                                                   "    fs_result    = result;\n"
4961                                                                   "    EmitVertex();\n"
4962                                                                   "    gl_Position  = vec4(1, -1, 0, 1);\n"
4963                                                                   "    fs_result    = result;\n"
4964                                                                   "    EmitVertex();\n"
4965                                                                   "    gl_Position  = vec4(1, 1, 0, 1);\n"
4966                                                                   "    fs_result    = result;\n"
4967                                                                   "    EmitVertex();\n"
4968                                                                   "}\n";
4969                 break;
4970
4971         default:
4972                 TCU_FAIL("Unrecognized shader object type.");
4973                 break;
4974         }
4975
4976         return geometry_shader_source;
4977 }
4978
4979 /** Prepare shader
4980  *
4981  * @tparam API                Tested API descriptor
4982  *
4983  * @param tested_shader_type  The type of shader that is being tested
4984  * @param function_definition Definition used to prepare shader
4985  * @param function_use        Snippet that makes use of defined function
4986  * @param verification        Snippet that verifies results
4987  **/
4988 template <class API>
4989 std::string InteractionFunctionCalls1<API>::prepare_tess_ctrl_shader(
4990         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4991         const std::string& function_use, const std::string& verification)
4992 {
4993         std::string tess_ctrl_shader_source;
4994
4995         switch (tested_shader_type)
4996         {
4997         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4998         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4999         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
5000         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
5001                 break;
5002
5003         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
5004                 tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
5005                                                                   "\n"
5006                                                                   "out float tcs_result[];\n"
5007                                                                   "\n";
5008
5009                 /* User-defined function definition. */
5010                 tess_ctrl_shader_source += function_definition;
5011                 tess_ctrl_shader_source += "\n\n";
5012
5013                 /* Main function definition. */
5014                 tess_ctrl_shader_source += shader_start;
5015                 tess_ctrl_shader_source += function_use;
5016                 tess_ctrl_shader_source += "\n\n";
5017                 tess_ctrl_shader_source += verification;
5018                 tess_ctrl_shader_source += "\n\n";
5019                 tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
5020                                                                    "\n"
5021                                                                    "    gl_TessLevelOuter[0] = 1.0;\n"
5022                                                                    "    gl_TessLevelOuter[1] = 1.0;\n"
5023                                                                    "    gl_TessLevelOuter[2] = 1.0;\n"
5024                                                                    "    gl_TessLevelOuter[3] = 1.0;\n"
5025                                                                    "    gl_TessLevelInner[0] = 1.0;\n"
5026                                                                    "    gl_TessLevelInner[1] = 1.0;\n"
5027                                                                    "}\n";
5028                 break;
5029
5030         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
5031                 tess_ctrl_shader_source = default_tc_shader_source;
5032                 break;
5033
5034         default:
5035                 TCU_FAIL("Unrecognized shader object type.");
5036                 break;
5037         }
5038
5039         return tess_ctrl_shader_source;
5040 }
5041
5042 /** Prepare shader
5043  *
5044  * @tparam API                Tested API descriptor
5045  *
5046  * @param tested_shader_type  The type of shader that is being tested
5047  * @param function_definition Definition used to prepare shader
5048  * @param function_use        Snippet that makes use of defined function
5049  * @param verification        Snippet that verifies results
5050  **/
5051 template <class API>
5052 std::string InteractionFunctionCalls1<API>::prepare_tess_eval_shader(
5053         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
5054         const std::string& function_use, const std::string& verification)
5055 {
5056         std::string tess_eval_shader_source;
5057
5058         switch (tested_shader_type)
5059         {
5060         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
5061         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
5062         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
5063         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
5064                 break;
5065
5066         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
5067                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
5068                                                                   "\n"
5069                                                                   "in  float tcs_result[];\n"
5070                                                                   "out float tes_result;\n"
5071                                                                   "\n"
5072                                                                   "void main()\n"
5073                                                                   "{\n"
5074                                                                   "    tes_result = tcs_result[0];\n"
5075                                                                   "}\n";
5076                 break;
5077
5078         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
5079                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
5080                                                                   "\n"
5081                                                                   "out float tes_result;\n"
5082                                                                   "\n";
5083
5084                 /* User-defined function definition. */
5085                 tess_eval_shader_source += function_definition;
5086                 tess_eval_shader_source += "\n\n";
5087
5088                 /* Main function definition. */
5089                 tess_eval_shader_source += shader_start;
5090                 tess_eval_shader_source += function_use;
5091                 tess_eval_shader_source += "\n\n";
5092                 tess_eval_shader_source += verification;
5093                 tess_eval_shader_source += "\n\n";
5094                 tess_eval_shader_source += "    tes_result = result;\n"
5095                                                                    "}\n";
5096                 break;
5097
5098         default:
5099                 TCU_FAIL("Unrecognized shader object type.");
5100                 break;
5101         }
5102
5103         return tess_eval_shader_source;
5104 }
5105
5106 /** Prepare shader
5107  *
5108  * @tparam API                Tested API descriptor
5109  *
5110  * @param tested_shader_type  The type of shader that is being tested
5111  * @param function_definition Definition used to prepare shader
5112  * @param function_use        Snippet that makes use of defined function
5113  * @param verification        Snippet that verifies results
5114  **/
5115 template <class API>
5116 std::string InteractionFunctionCalls1<API>::prepare_vertex_shader(
5117         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
5118         const std::string& function_use, const std::string& verification)
5119 {
5120         std::string vertex_shader_source;
5121
5122         switch (tested_shader_type)
5123         {
5124         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
5125                 break;
5126
5127         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
5128                 vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
5129                                                            "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
5130                                                            "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
5131                                                            "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
5132                                                            "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
5133                                                            "\n"
5134                                                            "void main()\n"
5135                                                            "{\n"
5136                                                            "    gl_Position = vertex_positions[gl_VertexID];"
5137                                                            "}\n\n";
5138                 break;
5139
5140         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
5141         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
5142         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
5143                 vertex_shader_source = default_vertex_shader_source;
5144                 break;
5145
5146         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
5147                 /* Vertex shader source. */
5148                 vertex_shader_source = "out float fs_result;\n\n";
5149                 vertex_shader_source += "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
5150                                                                 "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
5151                                                                 "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
5152                                                                 "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
5153                                                                 "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n\n";
5154
5155                 /* User-defined function definition. */
5156                 vertex_shader_source += function_definition;
5157                 vertex_shader_source += "\n\n";
5158
5159                 /* Main function definition. */
5160                 vertex_shader_source += shader_start;
5161                 vertex_shader_source += function_use;
5162                 vertex_shader_source += "\n\n";
5163                 vertex_shader_source += verification;
5164                 vertex_shader_source += "\n\n";
5165                 vertex_shader_source += "    fs_result   = result;\n"
5166                                                                 "    gl_Position = vertex_positions[gl_VertexID];\n";
5167                 vertex_shader_source += shader_end;
5168                 break;
5169
5170         default:
5171                 TCU_FAIL("Unrecognized shader object type.");
5172                 break;
5173         }
5174
5175         return vertex_shader_source;
5176 }
5177
5178 /* Generates the shader source code for the InteractionFunctionCalls2
5179  * array tests, and attempts to compile each test shader, for both
5180  * vertex and fragment shaders.
5181  *
5182  * @tparam API               Tested API descriptor
5183  *
5184  * @param tested_shader_type The type of shader that is being tested
5185  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5186  */
5187 template <class API>
5188 void InteractionFunctionCalls2<API>::test_shader_compilation(
5189         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5190 {
5191         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
5192                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
5193                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
5194                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
5195         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5196
5197         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
5198                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
5199                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
5200                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
5201                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
5202         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5203
5204         const std::string iteration_loop_end = "                }\n"
5205                                                                                    "            }\n"
5206                                                                                    "        }\n"
5207                                                                                    "    }\n";
5208         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5209                                                                                          "    {\n"
5210                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5211                                                                                          "        {\n"
5212                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5213                                                                                          "            {\n"
5214                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5215                                                                                          "                {\n";
5216         const std::string multiplier_array = "const int[] multiplier_array = int[]( 1,  2,  3,  4,  5,  6,  7,  8,\n"
5217                                                                                  "                                     11, 12, 13, 14, 15, 16, 17, 18,\n"
5218                                                                                  "                                     21, 22, 23, 24, 25, 26, 27, 28,\n"
5219                                                                                  "                                     31, 32, 33, 34, 35, 36, 37, 38,\n"
5220                                                                                  "                                     41, 42, 43, 44, 45, 46, 47, 48,\n"
5221                                                                                  "                                     51, 52, 53, 54, 55, 56, 57, 58,\n"
5222                                                                                  "                                     61, 62, 63, 64, 65, 66, 67, 68,\n"
5223                                                                                  "                                     71, 72, 73, 74, 75, 76, 77, 78,\n"
5224                                                                                  "                                     81, 82, 83, 84, 85, 86, 87, 88);\n";
5225         const glcts::test_var_type* var_types_set = var_types_set_es;
5226         size_t                                          num_var_types = num_var_types_es;
5227         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5228
5229         if (API::USE_DOUBLE)
5230         {
5231                 var_types_set = var_types_set_gl;
5232                 num_var_types = num_var_types_gl;
5233         }
5234
5235         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5236         {
5237                 _supported_variable_types_map_const_iterator var_iterator =
5238                         supported_variable_types_map.find(var_types_set[var_type_index]);
5239
5240                 if (var_iterator != supported_variable_types_map.end())
5241                 {
5242                         std::string function_definition;
5243                         std::string function_use;
5244                         std::string verification;
5245
5246                         function_definition += multiplier_array;
5247                         function_definition += "void my_function(inout ";
5248                         function_definition += var_iterator->second.type;
5249                         function_definition += " inout_array[2][2][2][2]) {\n"
5250                                                                    "    uint i = 0u;\n";
5251                         function_definition += iteration_loop_start;
5252                         function_definition += "                                   inout_array[a][b][c][d] *= " +
5253                                                                    var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n";
5254                         function_definition += "                                   i+= 1u;\n";
5255                         function_definition += iteration_loop_end;
5256                         function_definition += "}";
5257
5258                         function_use += "    float result = 1.0;\n";
5259                         function_use += "    uint iterator = 0u;\n";
5260                         function_use += "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
5261                         function_use += iteration_loop_start;
5262                         function_use += "                                   my_array[a][b][c][d] = " +
5263                                                         var_iterator->second.variable_type_initializer2 + ";\n";
5264                         function_use += iteration_loop_end;
5265                         function_use += "    my_function(my_array);";
5266
5267                         verification += iteration_loop_start;
5268                         verification += "                                   if (my_array[a][b][c][d] " +
5269                                                         var_iterator->second.specific_element + "!= " + var_iterator->second.iterator_type +
5270                                                         "(multiplier_array[iterator % 64u]))\n"
5271                                                         "                                   {\n"
5272                                                         "                                       result = 0.0;\n"
5273                                                         "                                   }\n"
5274                                                         "                                   iterator += 1u;\n";
5275                         verification += iteration_loop_end;
5276
5277                         if (false == test_compute)
5278                         {
5279                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5280                         }
5281                         else
5282                         {
5283                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5284                         }
5285
5286                         /* Deallocate any resources used. */
5287                         this->delete_objects();
5288                 } /* if var_type iterator found */
5289                 else
5290                 {
5291                         TCU_FAIL("Type not found.");
5292                 }
5293         } /* for (int var_type_index = 0; ...) */
5294 }
5295
5296 /* Generates the shader source code for the InteractionArgumentAliasing1
5297  * array tests, and attempts to compile each test shader, for both
5298  * vertex and fragment shaders.
5299  *
5300  * @tparam API               Tested API descriptor
5301  *
5302  * @param tested_shader_type The type of shader that is being tested
5303  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5304  */
5305 template <class API>
5306 void InteractionArgumentAliasing1<API>::test_shader_compilation(
5307         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5308 {
5309         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5310         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5311
5312         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5313                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5314         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5315
5316         const std::string iteration_loop_end = "                }\n"
5317                                                                                    "            }\n"
5318                                                                                    "        }\n"
5319                                                                                    "    }\n";
5320         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5321                                                                                          "    {\n"
5322                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5323                                                                                          "        {\n"
5324                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5325                                                                                          "            {\n"
5326                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5327                                                                                          "                {\n";
5328         const glcts::test_var_type* var_types_set = var_types_set_es;
5329         size_t                                          num_var_types = num_var_types_es;
5330         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5331
5332         if (API::USE_DOUBLE)
5333         {
5334                 var_types_set = var_types_set_gl;
5335                 num_var_types = num_var_types_gl;
5336         }
5337
5338         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5339         {
5340                 _supported_variable_types_map_const_iterator var_iterator =
5341                         supported_variable_types_map.find(var_types_set[var_type_index]);
5342
5343                 if (var_iterator != supported_variable_types_map.end())
5344                 {
5345                         std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n";
5346
5347                         std::string function_definition;
5348                         std::string function_use;
5349                         std::string verification;
5350
5351                         function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5352                         function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5353                         function_definition += "{\n";
5354                         function_definition += "    " + iteration_loop_start;
5355                         function_definition +=
5356                                 "                               x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
5357                         function_definition += "    " + iteration_loop_end;
5358                         function_definition += "\n";
5359                         function_definition += "    " + iteration_loop_start;
5360                         function_definition += "                                   if(y[a][b][c][d]";
5361                         if (var_iterator->second.type == "mat4") // mat4 comparison
5362                         {
5363                                 function_definition += "[0][0]";
5364                                 function_definition += " != float";
5365                         }
5366                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5367                         {
5368                                 function_definition += "[0][0]";
5369                                 function_definition += " != double";
5370                         }
5371                         else
5372                         {
5373                                 function_definition += " != ";
5374                                 function_definition += var_iterator->second.type;
5375                         }
5376                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5377                         function_definition += "    " + iteration_loop_end;
5378                         function_definition += "  return true;\n";
5379                         function_definition += "}";
5380
5381                         function_use += "    " + array_declaration;
5382                         function_use += "    " + iteration_loop_start;
5383                         function_use += "                                   z[a][b][c][d] = ";
5384                         function_use += var_iterator->second.type;
5385                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5386                         function_use += "    " + iteration_loop_end;
5387
5388                         verification += "    float result = 0.0;\n";
5389                         verification += "    if(gfunc(z, z) == true)\n";
5390                         verification += "    {\n";
5391                         verification += "        result = 1.0;\n\n";
5392                         verification += "    }\n";
5393                         verification += "    else\n";
5394                         verification += "    {\n";
5395                         verification += "        result = 0.0;\n\n";
5396                         verification += "    }\n";
5397
5398                         if (false == test_compute)
5399                         {
5400                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5401                         }
5402                         else
5403                         {
5404                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5405                         }
5406
5407                         /* Deallocate any resources used. */
5408                         this->delete_objects();
5409                 } /* if var_type iterator found */
5410                 else
5411                 {
5412                         TCU_FAIL("Type not found.");
5413                 }
5414         }
5415 }
5416
5417 /* Generates the shader source code for the InteractionArgumentAliasing2
5418  * array tests, and attempts to compile each test shader, for both
5419  * vertex and fragment shaders.
5420  *
5421  * @tparam API               Tested API descriptor
5422  *
5423  * @param tested_shader_type The type of shader that is being tested
5424  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5425  */
5426 template <class API>
5427 void InteractionArgumentAliasing2<API>::test_shader_compilation(
5428         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5429 {
5430         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5431         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5432
5433         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5434                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5435         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5436
5437         const std::string iteration_loop_end = "                }\n"
5438                                                                                    "            }\n"
5439                                                                                    "        }\n"
5440                                                                                    "    }\n";
5441         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5442                                                                                          "    {\n"
5443                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5444                                                                                          "        {\n"
5445                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5446                                                                                          "            {\n"
5447                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5448                                                                                          "                {\n";
5449         const glcts::test_var_type* var_types_set = var_types_set_es;
5450         size_t                                          num_var_types = num_var_types_es;
5451         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5452
5453         if (API::USE_DOUBLE)
5454         {
5455                 var_types_set = var_types_set_gl;
5456                 num_var_types = num_var_types_gl;
5457         }
5458
5459         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5460         {
5461                 _supported_variable_types_map_const_iterator var_iterator =
5462                         supported_variable_types_map.find(var_types_set[var_type_index]);
5463
5464                 if (var_iterator != supported_variable_types_map.end())
5465                 {
5466                         std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n";
5467
5468                         std::string function_definition;
5469                         std::string function_use;
5470                         std::string verification;
5471
5472                         function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5473                         function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5474                         function_definition += "{\n";
5475                         function_definition += "    " + iteration_loop_start;
5476                         function_definition +=
5477                                 "                                   y[a][b][c][d] = " + var_iterator->second.type +
5478                                 "(123);\n";
5479                         function_definition += "    " + iteration_loop_end;
5480                         function_definition += "\n";
5481                         function_definition += "    " + iteration_loop_start;
5482                         function_definition += "                                   if(x[a][b][c][d]";
5483                         if (var_iterator->second.type == "mat4") // mat4 comparison
5484                         {
5485                                 function_definition += "[0][0]";
5486                                 function_definition += " != float";
5487                         }
5488                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5489                         {
5490                                 function_definition += "[0][0]";
5491                                 function_definition += " != double";
5492                         }
5493                         else
5494                         {
5495                                 function_definition += " != ";
5496                                 function_definition += var_iterator->second.type;
5497                         }
5498                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5499                         function_definition += "    " + iteration_loop_end;
5500                         function_definition += "  return true;\n";
5501                         function_definition += "}";
5502
5503                         function_use += "    " + array_declaration;
5504                         function_use += "    " + iteration_loop_start;
5505                         function_use += "                                   z[a][b][c][d] = ";
5506                         function_use += var_iterator->second.type;
5507                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5508                         function_use += "    " + iteration_loop_end;
5509
5510                         verification += "    float result = 0.0;\n";
5511                         verification += "    if(gfunc(z, z) == true)\n";
5512                         verification += "    {\n";
5513                         verification += "        result = 1.0;\n\n";
5514                         verification += "    }\n";
5515                         verification += "    else\n";
5516                         verification += "    {\n";
5517                         verification += "        result = 0.0;\n\n";
5518                         verification += "    }\n";
5519
5520                         if (false == test_compute)
5521                         {
5522                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5523                         }
5524                         else
5525                         {
5526                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5527                         }
5528
5529                         /* Deallocate any resources used. */
5530                         this->delete_objects();
5531                 } /* if var_type iterator found */
5532                 else
5533                 {
5534                         TCU_FAIL("Type not found.");
5535                 }
5536         }
5537 }
5538
5539 /* Generates the shader source code for the InteractionArgumentAliasing3
5540  * array tests, and attempts to compile each test shader, for both
5541  * vertex and fragment shaders.
5542  *
5543  * @tparam API               Tested API descriptor
5544  *
5545  * @param tested_shader_type The type of shader that is being tested
5546  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5547  */
5548 template <class API>
5549 void InteractionArgumentAliasing3<API>::test_shader_compilation(
5550         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5551 {
5552         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5553         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5554
5555         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5556                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5557         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5558
5559         const std::string iteration_loop_end = "                }\n"
5560                                                                                    "            }\n"
5561                                                                                    "        }\n"
5562                                                                                    "    }\n";
5563         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5564                                                                                          "    {\n"
5565                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5566                                                                                          "        {\n"
5567                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5568                                                                                          "            {\n"
5569                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5570                                                                                          "                {\n";
5571         const glcts::test_var_type* var_types_set = var_types_set_es;
5572         size_t                                          num_var_types = num_var_types_es;
5573         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5574
5575         if (API::USE_DOUBLE)
5576         {
5577                 var_types_set = var_types_set_gl;
5578                 num_var_types = num_var_types_gl;
5579         }
5580
5581         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5582         {
5583                 _supported_variable_types_map_const_iterator var_iterator =
5584                         supported_variable_types_map.find(var_types_set[var_type_index]);
5585
5586                 if (var_iterator != supported_variable_types_map.end())
5587                 {
5588                         std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n";
5589
5590                         std::string function_definition;
5591                         std::string function_use;
5592                         std::string verification;
5593
5594                         function_definition += "bool gfunc(out " + var_iterator->second.type + " x[2][2][2][2], ";
5595                         function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5596                         function_definition += "{\n";
5597                         function_definition += "    " + iteration_loop_start;
5598                         function_definition +=
5599                                 "                                   x[a][b][c][d] = " + var_iterator->second.type +
5600                                 "(123);\n";
5601                         function_definition += "    " + iteration_loop_end;
5602                         function_definition += "\n";
5603                         function_definition += "    " + iteration_loop_start;
5604                         function_definition += "                                   if(y[a][b][c][d]";
5605                         if (var_iterator->second.type == "mat4") // mat4 comparison
5606                         {
5607                                 function_definition += "[0][0]";
5608                                 function_definition += " != float";
5609                         }
5610                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5611                         {
5612                                 function_definition += "[0][0]";
5613                                 function_definition += " != double";
5614                         }
5615                         else
5616                         {
5617                                 function_definition += " != ";
5618                                 function_definition += var_iterator->second.type;
5619                         }
5620                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5621                         function_definition += "    " + iteration_loop_end;
5622                         function_definition += "  return true;\n";
5623                         function_definition += "}\n\n";
5624
5625                         function_use += "    " + array_declaration;
5626                         function_use += "    " + iteration_loop_start;
5627                         function_use += "                                   z[a][b][c][d] = ";
5628                         function_use += var_iterator->second.type;
5629                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5630                         function_use += "    " + iteration_loop_end;
5631
5632                         verification += "    float result = 0.0;\n";
5633                         verification += "    if(gfunc(z, z) == true)\n";
5634                         verification += "    {\n";
5635                         verification += "        result = 1.0;\n\n";
5636                         verification += "    }\n";
5637                         verification += "    else\n";
5638                         verification += "    {\n";
5639                         verification += "        result = 0.0;\n\n";
5640                         verification += "    }\n";
5641
5642                         if (false == test_compute)
5643                         {
5644                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5645                         }
5646                         else
5647                         {
5648                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5649                         }
5650
5651                         /* Deallocate any resources used. */
5652                         this->delete_objects();
5653                 } /* if var_type iterator found */
5654                 else
5655                 {
5656                         TCU_FAIL("Type not found.");
5657                 }
5658         }
5659 }
5660
5661 /* Generates the shader source code for the InteractionArgumentAliasing4
5662  * array tests, and attempts to compile each test shader, for both
5663  * vertex and fragment shaders.
5664  *
5665  * @tparam API               Tested API descriptor
5666  *
5667  * @param tested_shader_type The type of shader that is being tested
5668  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5669  */
5670 template <class API>
5671 void InteractionArgumentAliasing4<API>::test_shader_compilation(
5672         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5673 {
5674         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5675         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5676
5677         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5678                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5679         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5680
5681         const std::string iteration_loop_end = "                }\n"
5682                                                                                    "            }\n"
5683                                                                                    "        }\n"
5684                                                                                    "    }\n";
5685         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5686                                                                                          "    {\n"
5687                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5688                                                                                          "        {\n"
5689                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5690                                                                                          "            {\n"
5691                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5692                                                                                          "                {\n";
5693         const glcts::test_var_type* var_types_set = var_types_set_es;
5694         size_t                                          num_var_types = num_var_types_es;
5695         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5696
5697         if (API::USE_DOUBLE)
5698         {
5699                 var_types_set = var_types_set_gl;
5700                 num_var_types = num_var_types_gl;
5701         }
5702
5703         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5704         {
5705                 _supported_variable_types_map_const_iterator var_iterator =
5706                         supported_variable_types_map.find(var_types_set[var_type_index]);
5707
5708                 if (var_iterator != supported_variable_types_map.end())
5709                 {
5710                         std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n";
5711
5712                         std::string function_definition;
5713                         std::string function_use;
5714                         std::string verification;
5715
5716                         function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5717                         function_definition += "out " + var_iterator->second.type + " y[2][2][2][2])\n";
5718                         function_definition += "{\n";
5719                         function_definition += "    " + iteration_loop_start;
5720                         function_definition +=
5721                                 "                                   y[a][b][c][d] = " + var_iterator->second.type +
5722                                 "(123);\n";
5723                         function_definition += "    " + iteration_loop_end;
5724                         function_definition += "\n";
5725                         function_definition += "    " + iteration_loop_start;
5726                         function_definition += "                                   if(x[a][b][c][d]";
5727                         if (var_iterator->second.type == "mat4") // mat4 comparison
5728                         {
5729                                 function_definition += "[0][0]";
5730                                 function_definition += " != float";
5731                         }
5732                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5733                         {
5734                                 function_definition += "[0][0]";
5735                                 function_definition += " != double";
5736                         }
5737                         else
5738                         {
5739                                 function_definition += " != ";
5740                                 function_definition += var_iterator->second.type;
5741                         }
5742                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5743                         function_definition += "    " + iteration_loop_end;
5744                         function_definition += "  return true;\n";
5745                         function_definition += "}\n\n";
5746
5747                         function_use += "    " + array_declaration;
5748                         function_use += "    " + iteration_loop_start;
5749                         function_use += "                                   z[a][b][c][d] = ";
5750                         function_use += var_iterator->second.type;
5751                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5752                         function_use += "    " + iteration_loop_end;
5753
5754                         verification += "    float result = 0.0;\n";
5755                         verification += "    if(gfunc(z, z) == true)\n";
5756                         verification += "    {\n";
5757                         verification += "        result = 1.0;\n\n";
5758                         verification += "    }\n";
5759                         verification += "    else\n";
5760                         verification += "    {\n";
5761                         verification += "        result = 0.0;\n\n";
5762                         verification += "    }\n";
5763
5764                         if (false == test_compute)
5765                         {
5766                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5767                         }
5768                         else
5769                         {
5770                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5771                         }
5772
5773                         /* Deallocate any resources used. */
5774                         this->delete_objects();
5775                 } /* if var_type iterator found */
5776                 else
5777                 {
5778                         TCU_FAIL("Type not found.");
5779                 }
5780         }
5781 }
5782
5783 /* Generates the shader source code for the InteractionArgumentAliasing3
5784  * array tests, and attempts to compile each test shader, for both
5785  * vertex and fragment shaders.
5786  *
5787  * @tparam API               Tested API descriptor
5788  *
5789  * @param tested_shader_type The type of shader that is being tested
5790  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5791  */
5792 template <class API>
5793 void InteractionArgumentAliasing5<API>::test_shader_compilation(
5794         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5795 {
5796         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5797         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5798
5799         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5800                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5801         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5802
5803         const std::string iteration_loop_end = "                }\n"
5804                                                                                    "            }\n"
5805                                                                                    "        }\n"
5806                                                                                    "    }\n";
5807         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5808                                                                                          "    {\n"
5809                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5810                                                                                          "        {\n"
5811                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5812                                                                                          "            {\n"
5813                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5814                                                                                          "                {\n";
5815         const glcts::test_var_type* var_types_set = var_types_set_es;
5816         size_t                                          num_var_types = num_var_types_es;
5817         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5818
5819         if (API::USE_DOUBLE)
5820         {
5821                 var_types_set = var_types_set_gl;
5822                 num_var_types = num_var_types_gl;
5823         }
5824
5825         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5826         {
5827                 _supported_variable_types_map_const_iterator var_iterator =
5828                         supported_variable_types_map.find(var_types_set[var_type_index]);
5829
5830                 if (var_iterator != supported_variable_types_map.end())
5831                 {
5832                         std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n";
5833
5834                         std::string function_definition;
5835                         std::string function_use;
5836                         std::string verification;
5837
5838                         function_definition += "bool gfunc(inout " + var_iterator->second.type + " x[2][2][2][2], ";
5839                         function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5840                         function_definition += "{\n";
5841                         function_definition += "    " + iteration_loop_start;
5842                         function_definition +=
5843                                 "                                   x[a][b][c][d] = " + var_iterator->second.type +
5844                                 "(123);\n";
5845                         function_definition += "    " + iteration_loop_end;
5846                         function_definition += "\n";
5847                         function_definition += "    " + iteration_loop_start;
5848                         function_definition += "                                   if(y[a][b][c][d]";
5849                         if (var_iterator->second.type == "mat4") // mat4 comparison
5850                         {
5851                                 function_definition += "[0][0]";
5852                                 function_definition += " != float";
5853                         }
5854                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5855                         {
5856                                 function_definition += "[0][0]";
5857                                 function_definition += " != double";
5858                         }
5859                         else
5860                         {
5861                                 function_definition += " != ";
5862                                 function_definition += var_iterator->second.type;
5863                         }
5864                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5865                         function_definition += "    " + iteration_loop_end;
5866                         function_definition += "  return true;\n";
5867                         function_definition += "}\n\n";
5868
5869                         function_use += "    " + array_declaration;
5870                         function_use += "    " + iteration_loop_start;
5871                         function_use += "                                   z[a][b][c][d] = ";
5872                         function_use += var_iterator->second.type;
5873                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5874                         function_use += "    " + iteration_loop_end;
5875
5876                         verification += "    float result = 0.0;\n";
5877                         verification += "    if(gfunc(z, z) == true)\n";
5878                         verification += "    {\n";
5879                         verification += "        result = 1.0;\n\n";
5880                         verification += "    }\n";
5881                         verification += "    else\n";
5882                         verification += "    {\n";
5883                         verification += "        result = 0.0;\n\n";
5884                         verification += "    }\n";
5885
5886                         if (false == test_compute)
5887                         {
5888                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5889                         }
5890                         else
5891                         {
5892                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5893                         }
5894
5895                         /* Deallocate any resources used. */
5896                         this->delete_objects();
5897                 } /* if var_type iterator found */
5898                 else
5899                 {
5900                         TCU_FAIL("Type not found.");
5901                 }
5902         }
5903 }
5904
5905 /* Generates the shader source code for the InteractionArgumentAliasing4
5906  * array tests, and attempts to compile each test shader, for both
5907  * vertex and fragment shaders.
5908  *
5909  * @tparam API               Tested API descriptor
5910  *
5911  * @param tested_shader_type The type of shader that is being tested
5912  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5913  */
5914 template <class API>
5915 void InteractionArgumentAliasing6<API>::test_shader_compilation(
5916         typename TestCaseBase<API>::TestShaderType tested_shader_type)
5917 {
5918         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5919         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5920
5921         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5922                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5923         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5924
5925         const std::string iteration_loop_end = "                }\n"
5926                                                                                    "            }\n"
5927                                                                                    "        }\n"
5928                                                                                    "    }\n";
5929         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5930                                                                                          "    {\n"
5931                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
5932                                                                                          "        {\n"
5933                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
5934                                                                                          "            {\n"
5935                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
5936                                                                                          "                {\n";
5937         const glcts::test_var_type* var_types_set = var_types_set_es;
5938         size_t                                          num_var_types = num_var_types_es;
5939         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5940
5941         if (API::USE_DOUBLE)
5942         {
5943                 var_types_set = var_types_set_gl;
5944                 num_var_types = num_var_types_gl;
5945         }
5946
5947         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5948         {
5949                 _supported_variable_types_map_const_iterator var_iterator =
5950                         supported_variable_types_map.find(var_types_set[var_type_index]);
5951
5952                 if (var_iterator != supported_variable_types_map.end())
5953                 {
5954                         std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n";
5955
5956                         std::string function_definition;
5957                         std::string function_use;
5958                         std::string verification;
5959
5960                         function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5961                         function_definition += "inout " + var_iterator->second.type + " y[2][2][2][2])\n";
5962                         function_definition += "{\n";
5963                         function_definition += "    " + iteration_loop_start;
5964                         function_definition +=
5965                                 "                                   y[a][b][c][d] = " + var_iterator->second.type +
5966                                 "(123);\n";
5967                         function_definition += "    " + iteration_loop_end;
5968                         function_definition += "\n";
5969                         function_definition += "    " + iteration_loop_start;
5970                         function_definition += "                                   if(x[a][b][c][d]";
5971                         if (var_iterator->second.type == "mat4") // mat4 comparison
5972                         {
5973                                 function_definition += "[0][0]";
5974                                 function_definition += " != float";
5975                         }
5976                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5977                         {
5978                                 function_definition += "[0][0]";
5979                                 function_definition += " != double";
5980                         }
5981                         else
5982                         {
5983                                 function_definition += " != ";
5984                                 function_definition += var_iterator->second.type;
5985                         }
5986                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5987                         function_definition += "    " + iteration_loop_end;
5988                         function_definition += "  return true;\n";
5989                         function_definition += "}\n\n";
5990
5991                         function_use += "    " + array_declaration;
5992                         function_use += "    " + iteration_loop_start;
5993                         function_use += "                                   z[a][b][c][d] = ";
5994                         function_use += var_iterator->second.type;
5995                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5996                         function_use += "    " + iteration_loop_end;
5997
5998                         verification += "    float result = 0.0;\n";
5999                         verification += "    if(gfunc(z, z) == true)\n";
6000                         verification += "    {\n";
6001                         verification += "        result = 1.0;\n\n";
6002                         verification += "    }\n";
6003                         verification += "    else\n";
6004                         verification += "    {\n";
6005                         verification += "        result = 0.0;\n\n";
6006                         verification += "    }\n";
6007
6008                         if (false == test_compute)
6009                         {
6010                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
6011                         }
6012                         else
6013                         {
6014                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
6015                         }
6016
6017                         /* Deallocate any resources used. */
6018                         this->delete_objects();
6019                 } /* if var_type iterator found */
6020                 else
6021                 {
6022                         TCU_FAIL("Type not found.");
6023                 }
6024         }
6025 }
6026
6027 /* Generates the shader source code for the InteractionUniforms1
6028  * array tests, and attempts to compile each test shader, for both
6029  * vertex and fragment shaders.
6030  *
6031  * @tparam API               Tested API descriptor
6032  *
6033  * @param tested_shader_type The type of shader that is being tested
6034  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6035  */
6036 template <class API>
6037 void InteractionUniforms1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
6038 {
6039         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
6040         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6041
6042         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
6043                                                                                                                          VAR_TYPE_DOUBLE };
6044         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6045
6046         const glw::Functions&           gl                        = this->context_id.getRenderContext().getFunctions();
6047         const glcts::test_var_type* var_types_set = var_types_set_es;
6048         size_t                                          num_var_types = num_var_types_es;
6049
6050         if (API::USE_DOUBLE)
6051         {
6052                 var_types_set = var_types_set_gl;
6053                 num_var_types = num_var_types_gl;
6054         }
6055
6056         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6057         {
6058                 _supported_variable_types_map_const_iterator var_iterator =
6059                         supported_variable_types_map.find(var_types_set[var_type_index]);
6060
6061                 if (var_iterator != supported_variable_types_map.end())
6062                 {
6063                         std::string uniform_definition;
6064                         std::string uniform_use;
6065
6066                         uniform_definition += "uniform ";
6067                         uniform_definition += var_iterator->second.precision;
6068                         uniform_definition += " ";
6069                         uniform_definition += var_iterator->second.type;
6070                         uniform_definition += " my_uniform_1[1][1][1][1];\n\n";
6071
6072                         uniform_use = "    float result = float(my_uniform_1[0][0][0][0]);\n";
6073
6074                         if (API::USE_ALL_SHADER_STAGES)
6075                         {
6076                                 const std::string& compute_shader_source =
6077                                         this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use);
6078                                 const std::string& fragment_shader_source =
6079                                         this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6080                                 const std::string& geometry_shader_source =
6081                                         this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use);
6082                                 const std::string& tess_ctrl_shader_source =
6083                                         this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use);
6084                                 const std::string& tess_eval_shader_source =
6085                                         this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use);
6086                                 const std::string& vertex_shader_source =
6087                                         this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6088
6089                                 switch (tested_shader_type)
6090                                 {
6091                                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
6092                                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6093                                         this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6094                                         break;
6095
6096                                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6097                                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6098                                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
6099                                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6100                                         this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
6101                                                                                                 geometry_shader_source, fragment_shader_source, compute_shader_source,
6102                                                                                                 false, false);
6103                                         break;
6104
6105                                 default:
6106                                         TCU_FAIL("Invalid enum");
6107                                         break;
6108                                 }
6109                         }
6110                         else
6111                         {
6112                                 const std::string& fragment_shader_source =
6113                                         this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6114                                 const std::string& vertex_shader_source =
6115                                         this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6116
6117                                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6118                         }
6119
6120                         glw::GLint uniform_location = -1;
6121
6122                         /* Make program object active. */
6123                         gl.useProgram(this->program_object_id);
6124                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
6125
6126                         /* Get uniform location. */
6127                         uniform_location = gl.getUniformLocation(this->program_object_id, "my_uniform_1[0][0][0][0]");
6128                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
6129
6130                         if (uniform_location == -1)
6131                         {
6132                                 TCU_FAIL("Uniform is not found or is considered as not active.");
6133                         }
6134
6135                         switch (var_type_index)
6136                         {
6137                         case 0: //float type of uniform is considered
6138                         {
6139                                 glw::GLfloat uniform_value = 1.0f;
6140
6141                                 gl.uniform1f(uniform_location, uniform_value);
6142                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() failed.");
6143
6144                                 break;
6145                         }
6146                         case 1: //int type of uniform is considered
6147                         {
6148                                 glw::GLint uniform_value = 1;
6149
6150                                 gl.uniform1i(uniform_location, uniform_value);
6151                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
6152
6153                                 break;
6154                         }
6155                         case 2: //uint type of uniform is considered
6156                         {
6157                                 glw::GLuint uniform_value = 1;
6158
6159                                 gl.uniform1ui(uniform_location, uniform_value);
6160                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1ui() failed.");
6161
6162                                 break;
6163                         }
6164                         case 3: //double type of uniform is considered
6165                         {
6166                                 glw::GLdouble uniform_value = 1.0;
6167
6168                                 gl.uniform1d(uniform_location, uniform_value);
6169                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1d() failed.");
6170
6171                                 break;
6172                         }
6173                         default:
6174                         {
6175                                 TCU_FAIL("Invalid variable-type index.");
6176
6177                                 break;
6178                         }
6179                         } /* switch (var_type_index) */
6180
6181                         /* Deallocate any resources used. */
6182                         this->delete_objects();
6183                 } /* if var_type iterator found */
6184                 else
6185                 {
6186                         TCU_FAIL("Type not found.");
6187                 }
6188         } /* for (int var_type_index = 0; ...) */
6189 }
6190
6191 /** Prepare shader
6192  *
6193  * @tparam API               Tested API descriptor
6194  *
6195  * @param tested_shader_type The type of shader that is being tested
6196  * @param uniform_definition Definition used to prepare shader
6197  * @param uniform_use        Snippet that use defined uniform
6198  **/
6199 template <class API>
6200 std::string InteractionUniforms1<API>::prepare_compute_shader(
6201         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6202         const std::string& uniform_use)
6203 {
6204         std::string compute_shader_source;
6205
6206         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
6207         {
6208                 compute_shader_source = "writeonly uniform image2D uni_image;\n"
6209                                                                 "\n";
6210
6211                 /* User-defined function definition. */
6212                 compute_shader_source += uniform_definition;
6213                 compute_shader_source += "\n\n";
6214
6215                 /* Main function definition. */
6216                 compute_shader_source += shader_start;
6217                 compute_shader_source += uniform_use;
6218                 compute_shader_source += "\n\n";
6219                 compute_shader_source += "\n"
6220                                                                  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
6221                                                                  "}\n"
6222                                                                  "\n";
6223         }
6224
6225         return compute_shader_source;
6226 }
6227
6228 /** Prepare shader
6229  *
6230  * @tparam API               Tested API descriptor
6231  *
6232  * @param tested_shader_type The type of shader that is being tested
6233  * @param uniform_definition Definition used to prepare shader
6234  * @param uniform_use        Snippet that use defined uniform
6235  **/
6236 template <class API>
6237 std::string InteractionUniforms1<API>::prepare_fragment_shader(
6238         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6239         const std::string& uniform_use)
6240 {
6241         std::string fragment_shader_source;
6242
6243         switch (tested_shader_type)
6244         {
6245         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6246                 break;
6247
6248         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6249                 fragment_shader_source = "out vec4 colour;\n\n";
6250
6251                 /* User-defined function definition. */
6252                 fragment_shader_source += uniform_definition;
6253                 fragment_shader_source += "\n\n";
6254
6255                 /* Main function definition. */
6256                 fragment_shader_source += shader_start;
6257                 fragment_shader_source += uniform_use;
6258                 fragment_shader_source += "\n\n";
6259                 fragment_shader_source += "    colour = vec4(result);\n";
6260                 fragment_shader_source += shader_end;
6261                 break;
6262
6263         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6264         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6265         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6266                 fragment_shader_source = "in float fs_result;\n\n"
6267                                                                  "out vec4 colour;\n\n"
6268                                                                  "void main()\n"
6269                                                                  "{\n"
6270                                                                  "    colour =  vec4(fs_result);\n"
6271                                                                  "}\n"
6272                                                                  "\n";
6273                 break;
6274
6275         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6276                 fragment_shader_source = default_fragment_shader_source;
6277                 break;
6278
6279         default:
6280                 TCU_FAIL("Unrecognized shader object type.");
6281                 break;
6282         }
6283
6284         return fragment_shader_source;
6285 }
6286
6287 /** Prepare shader
6288  *
6289  * @tparam API               Tested API descriptor
6290  *
6291  * @param tested_shader_type The type of shader that is being tested
6292  * @param uniform_definition Definition used to prepare shader
6293  * @param uniform_use        Snippet that use defined uniform
6294  **/
6295 template <class API>
6296 std::string InteractionUniforms1<API>::prepare_geometry_shader(
6297         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6298         const std::string& uniform_use)
6299 {
6300         std::string geometry_shader_source;
6301
6302         switch (tested_shader_type)
6303         {
6304         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6305         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6306         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6307                 break;
6308
6309         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6310         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6311                 geometry_shader_source = "layout(points)                           in;\n"
6312                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
6313                                                                  "\n"
6314                                                                  "in  float tes_result[];\n"
6315                                                                  "out float fs_result;\n"
6316                                                                  "\n"
6317                                                                  "void main()\n"
6318                                                                  "{\n"
6319                                                                  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
6320                                                                  "    fs_result    = tes_result[0];\n"
6321                                                                  "    EmitVertex();\n"
6322                                                                  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
6323                                                                  "    fs_result    = tes_result[0];\n"
6324                                                                  "    EmitVertex();\n"
6325                                                                  "    gl_Position  = vec4(1, -1, 0, 1);\n"
6326                                                                  "    fs_result    = tes_result[0];\n"
6327                                                                  "    EmitVertex();\n"
6328                                                                  "    gl_Position  = vec4(1, 1, 0, 1);\n"
6329                                                                  "    fs_result    = tes_result[0];\n"
6330                                                                  "    EmitVertex();\n"
6331                                                                  "}\n";
6332                 break;
6333
6334         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6335                 geometry_shader_source = "layout(points)                           in;\n"
6336                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
6337                                                                  "\n"
6338                                                                  "out float fs_result;\n"
6339                                                                  "\n";
6340
6341                 /* User-defined function definition. */
6342                 geometry_shader_source += uniform_definition;
6343                 geometry_shader_source += "\n\n";
6344
6345                 /* Main function definition. */
6346                 geometry_shader_source += shader_start;
6347                 geometry_shader_source += uniform_use;
6348                 geometry_shader_source += "\n\n";
6349                 geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
6350                                                                   "    fs_result    = result;\n"
6351                                                                   "    EmitVertex();\n"
6352                                                                   "    gl_Position  = vec4(-1, 1, 0, 1);\n"
6353                                                                   "    fs_result    = result;\n"
6354                                                                   "    EmitVertex();\n"
6355                                                                   "    gl_Position  = vec4(1, -1, 0, 1);\n"
6356                                                                   "    fs_result    = result;\n"
6357                                                                   "    EmitVertex();\n"
6358                                                                   "    gl_Position  = vec4(1, 1, 0, 1);\n"
6359                                                                   "    fs_result    = result;\n"
6360                                                                   "    EmitVertex();\n"
6361                                                                   "}\n";
6362                 break;
6363
6364         default:
6365                 TCU_FAIL("Unrecognized shader object type.");
6366                 break;
6367         }
6368
6369         return geometry_shader_source;
6370 }
6371
6372 /** Prepare shader
6373  *
6374  * @tparam API               Tested API descriptor
6375  *
6376  * @param tested_shader_type The type of shader that is being tested
6377  * @param uniform_definition Definition used to prepare shader
6378  * @param uniform_use        Snippet that use defined uniform
6379  **/
6380 template <class API>
6381 std::string InteractionUniforms1<API>::prepare_tess_ctrl_shader(
6382         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6383         const std::string& uniform_use)
6384 {
6385         std::string tess_ctrl_shader_source;
6386
6387         switch (tested_shader_type)
6388         {
6389         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6390         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6391         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6392         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6393                 break;
6394
6395         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6396                 tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
6397                                                                   "\n"
6398                                                                   "out float tcs_result[];\n"
6399                                                                   "\n";
6400
6401                 /* User-defined function definition. */
6402                 tess_ctrl_shader_source += uniform_definition;
6403                 tess_ctrl_shader_source += "\n\n";
6404
6405                 /* Main function definition. */
6406                 tess_ctrl_shader_source += shader_start;
6407                 tess_ctrl_shader_source += uniform_use;
6408                 tess_ctrl_shader_source += "\n\n";
6409                 tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
6410                                                                    "\n"
6411                                                                    "    gl_TessLevelOuter[0] = 1.0;\n"
6412                                                                    "    gl_TessLevelOuter[1] = 1.0;\n"
6413                                                                    "    gl_TessLevelOuter[2] = 1.0;\n"
6414                                                                    "    gl_TessLevelOuter[3] = 1.0;\n"
6415                                                                    "    gl_TessLevelInner[0] = 1.0;\n"
6416                                                                    "    gl_TessLevelInner[1] = 1.0;\n"
6417                                                                    "}\n";
6418                 break;
6419
6420         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6421                 tess_ctrl_shader_source = default_tc_shader_source;
6422                 break;
6423
6424         default:
6425                 TCU_FAIL("Unrecognized shader object type.");
6426                 break;
6427         }
6428
6429         return tess_ctrl_shader_source;
6430 }
6431
6432 /** Prepare shader
6433  *
6434  * @tparam API               Tested API descriptor
6435  *
6436  * @param tested_shader_type The type of shader that is being tested
6437  * @param uniform_definition Definition used to prepare shader
6438  * @param uniform_use        Snippet that use defined uniform
6439  **/
6440 template <class API>
6441 std::string InteractionUniforms1<API>::prepare_tess_eval_shader(
6442         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6443         const std::string& uniform_use)
6444 {
6445         std::string tess_eval_shader_source;
6446
6447         switch (tested_shader_type)
6448         {
6449         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6450         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6451         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6452         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6453                 break;
6454
6455         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6456                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
6457                                                                   "\n"
6458                                                                   "in  float tcs_result[];\n"
6459                                                                   "out float tes_result;\n"
6460                                                                   "\n"
6461                                                                   "void main()\n"
6462                                                                   "{\n"
6463                                                                   "    tes_result = tcs_result[0];\n"
6464                                                                   "}\n";
6465                 break;
6466
6467         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6468                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
6469                                                                   "\n"
6470                                                                   "out float tes_result;\n"
6471                                                                   "\n";
6472
6473                 /* User-defined function definition. */
6474                 tess_eval_shader_source += uniform_definition;
6475                 tess_eval_shader_source += "\n\n";
6476
6477                 /* Main function definition. */
6478                 tess_eval_shader_source += shader_start;
6479                 tess_eval_shader_source += uniform_use;
6480                 tess_eval_shader_source += "\n\n";
6481                 tess_eval_shader_source += "    tes_result = result;\n"
6482                                                                    "}\n";
6483                 break;
6484
6485         default:
6486                 TCU_FAIL("Unrecognized shader object type.");
6487                 break;
6488         }
6489
6490         return tess_eval_shader_source;
6491 }
6492
6493 /** Prepare shader
6494  *
6495  * @tparam API               Tested API descriptor
6496  *
6497  * @param tested_shader_type The type of shader that is being tested
6498  * @param uniform_definition Definition used to prepare shader
6499  * @param uniform_use        Snippet that use defined uniform
6500  **/
6501 template <class API>
6502 std::string InteractionUniforms1<API>::prepare_vertex_shader(
6503         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6504         const std::string& uniform_use)
6505 {
6506         std::string vertex_shader_source;
6507
6508         switch (tested_shader_type)
6509         {
6510         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6511                 break;
6512
6513         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6514         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6515         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6516         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6517                 vertex_shader_source = default_vertex_shader_source;
6518                 break;
6519
6520         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6521                 /* User-defined function definition. */
6522                 vertex_shader_source += uniform_definition;
6523
6524                 /* Main function definition. */
6525                 vertex_shader_source += shader_start;
6526                 vertex_shader_source += uniform_use;
6527                 vertex_shader_source += "    gl_Position = vec4(result);\n";
6528                 vertex_shader_source += shader_end;
6529                 break;
6530
6531         default:
6532                 TCU_FAIL("Unrecognized shader object type.");
6533                 break;
6534         }
6535
6536         return vertex_shader_source;
6537 }
6538
6539 /* Generates the shader source code for the InteractionUniforms2
6540  * array tests, and attempts to compile each test shader, for both
6541  * vertex and fragment shaders.
6542  *
6543  * @tparam API               Tested API descriptor
6544  *
6545  * @param tested_shader_type The type of shader that is being tested
6546  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6547  */
6548 template <class API>
6549 void InteractionUniforms2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
6550 {
6551         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
6552         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6553
6554         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
6555                                                                                                                          VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
6556         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6557
6558         const std::string array_initializers[] = { "int[2][2][2][2](\n"
6559                                                                                            "    int[2][2][2](\n"
6560                                                                                            "        int[2][2](\n"
6561                                                                                            "            int[2]( 1,  2),\n"
6562                                                                                            "            int[2]( 3,  4)\n"
6563                                                                                            "        ),\n"
6564                                                                                            "        int[2][2](\n"
6565                                                                                            "            int[2]( 5,  6),\n"
6566                                                                                            "            int[2]( 7,  8)\n"
6567                                                                                            "        )\n"
6568                                                                                            "    ),\n"
6569                                                                                            "    int[2][2][2](\n"
6570                                                                                            "        int[2][2](\n"
6571                                                                                            "            int[2](11, 12),\n"
6572                                                                                            "            int[2](13, 14)\n"
6573                                                                                            "        ),\n"
6574                                                                                            "        int[2][2](\n"
6575                                                                                            "            int[2](15, 16),\n"
6576                                                                                            "            int[2](17, 18)\n"
6577                                                                                            "        )\n"
6578                                                                                            "    )\n"
6579                                                                                            ")",
6580
6581                                                                                            "float[2][2][2][2](\n"
6582                                                                                            "    float[2][2][2](\n"
6583                                                                                            "        float[2][2](\n"
6584                                                                                            "            float[2](1.0, 2.0),\n"
6585                                                                                            "            float[2](3.0, 4.0)),\n"
6586                                                                                            "        float[2][2](\n"
6587                                                                                            "            float[2](5.0, 6.0),\n"
6588                                                                                            "            float[2](7.0, 8.0))),\n"
6589                                                                                            "    float[2][2][2](\n"
6590                                                                                            "        float[2][2](\n"
6591                                                                                            "            float[2](1.1, 2.1),\n"
6592                                                                                            "            float[2](3.1, 4.1)\n"
6593                                                                                            "        ),\n"
6594                                                                                            "        float[2][2](\n"
6595                                                                                            "            float[2](5.1, 6.1),\n"
6596                                                                                            "            float[2](7.1, 8.1)\n"
6597                                                                                            "        )\n"
6598                                                                                            "    )\n"
6599                                                                                            ")",
6600
6601                                                                                            "mat4[2][2][2][2](\n"
6602                                                                                            "    mat4[2][2][2](\n"
6603                                                                                            "        mat4[2][2](\n"
6604                                                                                            "            mat4[2]( mat4(1),  mat4(2)),\n"
6605                                                                                            "            mat4[2]( mat4(3),  mat4(4))\n"
6606                                                                                            "        ),\n"
6607                                                                                            "        mat4[2][2](\n"
6608                                                                                            "            mat4[2](mat4(5),  mat4(6)),\n"
6609                                                                                            "            mat4[2](mat4(7),  mat4(8))\n"
6610                                                                                            "        )\n"
6611                                                                                            "    ),\n"
6612                                                                                            "    mat4[2][2][2](\n"
6613                                                                                            "        mat4[2][2](\n"
6614                                                                                            "            mat4[2](mat4(9),  mat4(10)),\n"
6615                                                                                            "            mat4[2](mat4(11),  mat4(12))\n"
6616                                                                                            "        ),\n"
6617                                                                                            "        mat4[2][2](\n"
6618                                                                                            "            mat4[2](mat4(13),  mat4(14)),\n"
6619                                                                                            "            mat4[2](mat4(15),  mat4(16))\n"
6620                                                                                            "        )\n"
6621                                                                                            "    )\n"
6622                                                                                            ")",
6623
6624                                                                                            "double[2][2][2][2](\n"
6625                                                                                            "    double[2][2][2](\n"
6626                                                                                            "        double[2][2](\n"
6627                                                                                            "            double[2](1.0, 2.0),\n"
6628                                                                                            "            double[2](3.0, 4.0)),\n"
6629                                                                                            "        double[2][2](\n"
6630                                                                                            "            double[2](5.0, 6.0),\n"
6631                                                                                            "            double[2](7.0, 8.0))),\n"
6632                                                                                            "    double[2][2][2](\n"
6633                                                                                            "        double[2][2](\n"
6634                                                                                            "            double[2](1.1, 2.1),\n"
6635                                                                                            "            double[2](3.1, 4.1)\n"
6636                                                                                            "        ),\n"
6637                                                                                            "        double[2][2](\n"
6638                                                                                            "            double[2](5.1, 6.1),\n"
6639                                                                                            "            double[2](7.1, 8.1)\n"
6640                                                                                            "        )\n"
6641                                                                                            "    )\n"
6642                                                                                            ")",
6643
6644                                                                                            "dmat4[2][2][2][2](\n"
6645                                                                                            "    dmat4[2][2][2](\n"
6646                                                                                            "        dmat4[2][2](\n"
6647                                                                                            "            dmat4[2]( dmat4(1),  dmat4(2)),\n"
6648                                                                                            "            dmat4[2]( dmat4(3),  dmat4(4))\n"
6649                                                                                            "        ),\n"
6650                                                                                            "        dmat4[2][2](\n"
6651                                                                                            "            dmat4[2](dmat4(5),  dmat4(6)),\n"
6652                                                                                            "            dmat4[2](dmat4(7),  dmat4(8))\n"
6653                                                                                            "        )\n"
6654                                                                                            "    ),\n"
6655                                                                                            "    dmat4[2][2][2](\n"
6656                                                                                            "        dmat4[2][2](\n"
6657                                                                                            "            dmat4[2](dmat4(9),   dmat4(10)),\n"
6658                                                                                            "            dmat4[2](dmat4(11),  dmat4(12))\n"
6659                                                                                            "        ),\n"
6660                                                                                            "        dmat4[2][2](\n"
6661                                                                                            "            dmat4[2](dmat4(13),  dmat4(14)),\n"
6662                                                                                            "            dmat4[2](dmat4(15),  dmat4(16))\n"
6663                                                                                            "        )\n"
6664                                                                                            "    )\n"
6665                                                                                            ")" };
6666
6667         const glcts::test_var_type* var_types_set = var_types_set_es;
6668         size_t                                          num_var_types = num_var_types_es;
6669
6670         if (API::USE_DOUBLE)
6671         {
6672                 var_types_set = var_types_set_gl;
6673                 num_var_types = num_var_types_gl;
6674         }
6675
6676         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6677         {
6678                 _supported_variable_types_map_const_iterator var_iterator =
6679                         supported_variable_types_map.find(var_types_set[var_type_index]);
6680
6681                 if (var_iterator != supported_variable_types_map.end())
6682                 {
6683                         std::string base_variable_string;
6684
6685                         for (int initialiser_selector = 1; initialiser_selector >= 0; initialiser_selector--)
6686                         {
6687                                 // We normally do all 16 possible permutations of [4][4][4][4] items (15..0).
6688                                 // However, in this case we will skip the case that will work,
6689                                 // so we'll merely process permutations 14..0
6690                                 for (int permutation_index = 14; permutation_index >= 0; permutation_index--)
6691                                 {
6692                                         base_variable_string =
6693                                                 "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " x";
6694
6695                                         // for all 4 possible sub_script entries
6696                                         for (int sub_script_entry_index = 3; sub_script_entry_index >= 0; sub_script_entry_index--)
6697                                         {
6698                                                 if (permutation_index & (1 << sub_script_entry_index))
6699                                                 {
6700                                                         // In this case, we'll use a valid sub_script
6701                                                         base_variable_string += "[2]";
6702                                                 }
6703                                                 else
6704                                                 {
6705                                                         // In this case, we'll use an invalid sub_script
6706                                                         base_variable_string += "[]";
6707                                                 }
6708                                         }
6709
6710                                         if (initialiser_selector == 0)
6711                                         {
6712                                                 // We'll use an initialiser
6713                                                 base_variable_string += " = " + array_initializers[var_type_index];
6714                                         }
6715
6716                                         base_variable_string += ";\n\n";
6717
6718                                         std::string shader_source = base_variable_string + shader_start;
6719
6720                                         /* End main */
6721                                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
6722
6723                                         /* Execute test:
6724                                          *
6725                                          * This will succeed in case of allowed unsized
6726                                          * declarations and when at least one of these is
6727                                          * true:
6728                                          *   1. There is an initialiser.
6729                                          *   2. Only the outermost dimension is unsized,
6730                                          *      as in [][2][2][2].
6731                                          */
6732                                         EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION &&
6733                                                                                         (initialiser_selector == 0 || permutation_index == 7),
6734                                                                                 tested_shader_type, shader_source);
6735                                 } /* for (int permutation_index = 14; ...) */
6736                         }        /* for (int initialiser_selector  = 1; ...) */
6737                 }                 /* if var_type iterator found */
6738                 else
6739                 {
6740                         TCU_FAIL("Type not found.");
6741                 }
6742         } /* for (int var_type_index = 0; ...) */
6743 }
6744
6745 /* Generates the shader source code for the InteractionUniformBuffers1
6746  * array tests, and attempts to compile each test shader, for both
6747  * vertex and fragment shaders.
6748  *
6749  * @tparam API               Tested API descriptor
6750  *
6751  * @param tested_shader_type The type of shader that is being tested
6752  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6753  */
6754 template <class API>
6755 void InteractionUniformBuffers1<API>::test_shader_compilation(
6756         typename TestCaseBase<API>::TestShaderType tested_shader_type)
6757 {
6758         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
6759         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6760
6761         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
6762                                                                                                                          VAR_TYPE_DOUBLE };
6763         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6764
6765         const glcts::test_var_type* var_types_set = var_types_set_es;
6766         size_t                                          num_var_types = num_var_types_es;
6767
6768         if (API::USE_DOUBLE)
6769         {
6770                 var_types_set = var_types_set_gl;
6771                 num_var_types = num_var_types_gl;
6772         }
6773
6774         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6775         {
6776                 _supported_variable_types_map_const_iterator var_iterator =
6777                         supported_variable_types_map.find(var_types_set[var_type_index]);
6778
6779                 if (var_iterator != supported_variable_types_map.end())
6780                 {
6781                         std::string shader_source;
6782
6783                         shader_source += "uniform uBlocka {\n";
6784                         shader_source += "    " + var_iterator->second.type + " x[1][1][1][1][1][1];\n";
6785                         shader_source += "};\n\n";
6786                         shader_source += shader_start;
6787
6788                         /* End main */
6789                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
6790
6791                         /* Execute test */
6792                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
6793                 } /* if var_type iterator found */
6794                 else
6795                 {
6796                         TCU_FAIL("Type not found.");
6797                 }
6798         }
6799 }
6800
6801 /* Generates the shader source code for the InteractionUniformBuffers2
6802  * array tests, and attempts to compile each test shader, for both
6803  * vertex and fragment shaders.
6804  *
6805  * @tparam API               Tested API descriptor
6806  *
6807  * @param tested_shader_type The type of shader that is being tested
6808  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6809  */
6810 template <class API>
6811 void InteractionUniformBuffers2<API>::test_shader_compilation(
6812         typename TestCaseBase<API>::TestShaderType tested_shader_type)
6813 {
6814         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
6815         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6816
6817         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
6818                                                                                                                          VAR_TYPE_DOUBLE };
6819         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6820
6821         const glw::Functions&           gl                        = this->context_id.getRenderContext().getFunctions();
6822         const glcts::test_var_type* var_types_set = var_types_set_es;
6823         size_t                                          num_var_types = num_var_types_es;
6824
6825         if (API::USE_DOUBLE)
6826         {
6827                 var_types_set = var_types_set_gl;
6828                 num_var_types = num_var_types_gl;
6829         }
6830
6831         /* Iterate through float / int / uint values. */
6832         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6833         {
6834                 _supported_variable_types_map_const_iterator var_iterator =
6835                         supported_variable_types_map.find(var_types_set[var_type_index]);
6836
6837                 if (var_iterator != supported_variable_types_map.end())
6838                 {
6839                         std::string uniform_definition;
6840                         std::string uniform_use;
6841
6842                         uniform_definition += "layout (std140) uniform uniform_block_name\n"
6843                                                                   "{\n";
6844                         uniform_definition += "    ";
6845                         uniform_definition += var_iterator->second.type;
6846                         uniform_definition += " my_uniform_1[1][1][1][1];\n"
6847                                                                   "};\n";
6848
6849                         uniform_use = "    float result = float(my_uniform_1[0][0][0][0]);\n";
6850
6851                         if (API::USE_ALL_SHADER_STAGES)
6852                         {
6853                                 const std::string& compute_shader_source =
6854                                         this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use);
6855                                 const std::string& fragment_shader_source =
6856                                         this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6857                                 const std::string& geometry_shader_source =
6858                                         this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use);
6859                                 const std::string& tess_ctrl_shader_source =
6860                                         this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use);
6861                                 const std::string& tess_eval_shader_source =
6862                                         this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use);
6863                                 const std::string& vertex_shader_source =
6864                                         this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6865
6866                                 switch (tested_shader_type)
6867                                 {
6868                                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
6869                                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6870                                         this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6871                                         break;
6872
6873                                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6874                                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6875                                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
6876                                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6877                                         this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
6878                                                                                                 geometry_shader_source, fragment_shader_source, compute_shader_source,
6879                                                                                                 false, false);
6880                                         break;
6881
6882                                 default:
6883                                         TCU_FAIL("Invalid enum");
6884                                         break;
6885                                 }
6886                         }
6887                         else
6888                         {
6889                                 const std::string& fragment_shader_source =
6890                                         this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6891                                 const std::string& vertex_shader_source =
6892                                         this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6893
6894                                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6895                         }
6896
6897                         glw::GLuint buffer_object_id       = 0;
6898                         glw::GLint  my_uniform_block_index = GL_INVALID_INDEX;
6899
6900                         gl.useProgram(this->program_object_id);
6901                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
6902
6903                         my_uniform_block_index = gl.getUniformBlockIndex(this->program_object_id, "uniform_block_name");
6904                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex() failed.");
6905
6906                         if ((unsigned)my_uniform_block_index == GL_INVALID_INDEX)
6907                         {
6908                                 TCU_FAIL("Uniform block not found or is considered as not active.");
6909                         }
6910
6911                         gl.genBuffers(1, &buffer_object_id);
6912                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed.");
6913
6914                         gl.bindBuffer(GL_UNIFORM_BUFFER, buffer_object_id);
6915                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed.");
6916
6917                         switch (var_type_index)
6918                         {
6919                         case 0: //float type of uniform is considered
6920                         {
6921                                 glw::GLfloat buffer_data[] = { 0.0f, 1.0f, 2.0f,  3.0f,  4.0f,  5.0f,  6.0f,  7.0f,
6922                                                                                            8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f };
6923
6924                                 gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6925                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6926
6927                                 break;
6928                         }               /* float case */
6929                         case 1: //int type of uniform is considered
6930                         {
6931
6932                                 glw::GLint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
6933
6934                                 gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6935                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6936
6937                                 break;
6938                         }               /* int case */
6939                         case 2: //uint type of uniform is considered
6940                         {
6941                                 glw::GLuint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
6942
6943                                 gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6944                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6945
6946                                 break;
6947                         }               /* uint case */
6948                         case 3: //double type of uniform is considered
6949                         {
6950                                 glw::GLdouble buffer_data[] = { 0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,
6951                                                                                                 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 };
6952
6953                                 gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6954                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6955
6956                                 break;
6957                         } /* double case */
6958                         default:
6959                         {
6960                                 TCU_FAIL("Invalid variable-type index.");
6961
6962                                 break;
6963                         }
6964                         } /* switch (var_type_index) */
6965
6966                         gl.uniformBlockBinding(this->program_object_id, my_uniform_block_index, 0);
6967                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding() failed.");
6968
6969                         gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, buffer_object_id);
6970                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed.");
6971
6972                         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type)
6973                         {
6974                                 execute_draw_test(tested_shader_type);
6975                         }
6976                         else
6977                         {
6978                                 execute_dispatch_test();
6979                         }
6980
6981                         /* Deallocate any resources used. */
6982                         gl.deleteBuffers(1, &buffer_object_id);
6983                         this->delete_objects();
6984                 } /* if var_type iterator found */
6985                 else
6986                 {
6987                         TCU_FAIL("Type not found.");
6988                 }
6989         } /* for (int var_type_index = 0; ...) */
6990 }
6991
6992 /** Executes test for compute program
6993  *
6994  * @tparam API Tested API descriptor
6995  **/
6996 template <class API>
6997 void InteractionUniformBuffers2<API>::execute_dispatch_test()
6998 {
6999         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7000
7001         gl.dispatchCompute(1, 1, 1);
7002         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7003 }
7004
7005 /** Executes test for draw program
7006  *
7007  * @tparam API               Tested API descriptor
7008  *
7009  * @param tested_shader_type The type of shader that is being tested
7010  **/
7011 template <class API>
7012 void InteractionUniformBuffers2<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type)
7013 {
7014         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7015
7016         glw::GLuint vao_id = 0;
7017
7018         gl.genVertexArrays(1, &vao_id);
7019         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
7020
7021         gl.bindVertexArray(vao_id);
7022         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
7023
7024         switch (tested_shader_type)
7025         {
7026         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7027         case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
7028         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7029                 gl.drawArrays(GL_POINTS, 0, 1);
7030                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7031                 break;
7032
7033         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
7034         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7035                 /* Tesselation patch set up */
7036                 gl.patchParameteri(GL_PATCH_VERTICES, 1);
7037                 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
7038
7039                 gl.drawArrays(GL_PATCHES, 0, 1);
7040                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7041                 break;
7042
7043         default:
7044                 TCU_FAIL("Invalid enum");
7045                 break;
7046         }
7047
7048         gl.deleteVertexArrays(1, &vao_id);
7049         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() failed.");
7050 }
7051
7052 /* Generates the shader source code for the InteractionUniformBuffers3
7053  * array tests, and attempts to compile each test shader, for both
7054  * vertex and fragment shaders.
7055  *
7056  * @tparam API               Tested API descriptor
7057  *
7058  * @param tested_shader_type The type of shader that is being tested
7059  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7060  */
7061 template <class API>
7062 void InteractionUniformBuffers3<API>::test_shader_compilation(
7063         typename TestCaseBase<API>::TestShaderType tested_shader_type)
7064 {
7065         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7066         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7067
7068         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7069                                                                                                                          VAR_TYPE_DOUBLE };
7070         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7071
7072         const std::string invalid_size_declarations[] = { "[2][2][2][]", "[2][2][][2]", "[2][][2][2]", "[][2][2][2]",
7073                                                                                                           "[2][2][][]",  "[2][][2][]",  "[][2][2][]",  "[2][][][2]",
7074                                                                                                           "[][2][][2]",  "[][][2][2]",  "[2][][][]",   "[][2][][]",
7075                                                                                                           "[][][2][]",   "[][][][2]",   "[][][][]" };
7076
7077         const std::string array_initializers[] = { "float[2][2][2][2](float[2][2][2](float[2][2](float[2](1.0, 2.0),"
7078                                                                                            "float[2](3.0, 4.0)),"
7079                                                                                            "float[2][2](float[2](5.0, 6.0),"
7080                                                                                            "float[2](7.0, 8.0))),"
7081                                                                                            "float[2][2][2](float[2][2](float[2](1.1, 2.1),"
7082                                                                                            "float[2](3.1, 4.1)),"
7083                                                                                            "float[2][2](float[2](5.1, 6.1),"
7084                                                                                            "float[2](7.1, 8.1))));\n",
7085
7086                                                                                            "int[2][2][2][2](int[2][2][2](int[2][2](int[2]( 1,  2),"
7087                                                                                            "int[2]( 3,  4)),"
7088                                                                                            "int[2][2](int[2]( 5,  6),"
7089                                                                                            "int[2]( 7,  8))),"
7090                                                                                            "int[2][2][2](int[2][2](int[2](11, 12),"
7091                                                                                            "int[2](13, 14)),"
7092                                                                                            "int[2][2](int[2](15, 16),"
7093                                                                                            "int[2](17, 18))));\n",
7094
7095                                                                                            "uint[2][2][2][2](uint[2][2][2](uint[2][2](uint[2]( 1u,  2u),"
7096                                                                                            "uint[2]( 3u,  4u)),"
7097                                                                                            "uint[2][2](uint[2]( 5u,  6u),"
7098                                                                                            "uint[2]( 7u,  8u))),"
7099                                                                                            "uint[2][2][2](uint[2][2](uint[2](11u, 12u),"
7100                                                                                            "uint[2](13u, 14u)),"
7101                                                                                            "uint[2][2](uint[2](15u, 16u),"
7102                                                                                            "uint[2](17u, 18u))));\n",
7103
7104                                                                                            "double[2][2][2][2](double[2][2][2](double[2][2](double[2](1.0, 2.0),"
7105                                                                                            "double[2](3.0, 4.0)),"
7106                                                                                            "double[2][2](double[2](5.0, 6.0),"
7107                                                                                            "double[2](7.0, 8.0))),"
7108                                                                                            "double[2][2][2](double[2][2](double[2](1.1, 2.1),"
7109                                                                                            "double[2](3.1, 4.1)),"
7110                                                                                            "double[2][2](double[2](5.1, 6.1),"
7111                                                                                            "double[2](7.1, 8.1))));\n" };
7112         const glcts::test_var_type* var_types_set = var_types_set_es;
7113         size_t                                          num_var_types = num_var_types_es;
7114
7115         if (API::USE_DOUBLE)
7116         {
7117                 var_types_set = var_types_set_gl;
7118                 num_var_types = num_var_types_gl;
7119         }
7120
7121         /* Iterate through float/ int/ uint types.
7122          * Case: without initializer.
7123          */
7124         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7125         {
7126                 _supported_variable_types_map_const_iterator var_iterator =
7127                         supported_variable_types_map.find(var_types_set[var_type_index]);
7128
7129                 if (var_iterator != supported_variable_types_map.end())
7130                 {
7131                         for (size_t invalid_size_declarations_index = 0;
7132                                  invalid_size_declarations_index <
7133                                  sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7134                                  invalid_size_declarations_index++)
7135                         {
7136                                 std::string shader_source;
7137
7138                                 shader_source = "layout (std140) uniform MyUniform {\n";
7139                                 shader_source += "    " + var_iterator->second.type +
7140                                                                  invalid_size_declarations[invalid_size_declarations_index] + " my_variable;\n";
7141                                 shader_source += "};\n\n";
7142                                 shader_source += shader_start;
7143
7144                                 /* End main */
7145                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7146
7147                                 /* Execute test */
7148                                 EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && invalid_size_declarations_index == 3,
7149                                                                         tested_shader_type, shader_source);
7150                         } /* for (int invalid_size_declarations_index = 0; ...) */
7151                 }
7152                 else
7153                 {
7154                         TCU_FAIL("Type not found.");
7155                 }
7156         } /* for (int var_type_index = 0; ...) */
7157
7158         /* Iterate through float/ int/ uint types.
7159          * Case: with initializer.
7160          */
7161         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7162         {
7163                 _supported_variable_types_map_const_iterator var_iterator =
7164                         supported_variable_types_map.find(var_types_set[var_type_index]);
7165
7166                 if (var_iterator != supported_variable_types_map.end())
7167                 {
7168                         for (size_t invalid_size_declarations_index = 0;
7169                                  invalid_size_declarations_index <
7170                                  sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7171                                  invalid_size_declarations_index++)
7172                         {
7173                                 std::string shader_source;
7174
7175                                 shader_source = "layout (std140) uniform MyUniform {\n";
7176                                 shader_source += "    " + var_iterator->second.type +
7177                                                                  invalid_size_declarations[invalid_size_declarations_index] +
7178                                                                  " my_variable = " + array_initializers[var_type_index];
7179
7180                                 var_iterator->second.type + invalid_size_declarations[invalid_size_declarations_index] +
7181                                         " my_variable = " + array_initializers[var_type_index];
7182                                 shader_source += "};\n\n";
7183                                 shader_source += shader_start;
7184
7185                                 /* End main */
7186                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7187
7188                                 /* Execute test */
7189                                 this->execute_negative_test(tested_shader_type, shader_source);
7190                         } /* for (int invalid_size_declarations_index = 0; ...) */
7191                 }        /* if var_type iterator found */
7192                 else
7193                 {
7194                         TCU_FAIL("Type not found.");
7195                 }
7196         } /* for (int var_type_index = 0; ...) */
7197 }
7198
7199 /* Generates the shader source code for the InteractionStorageBuffers1
7200  * array tests, and attempts to compile each test shader, for both
7201  * vertex and fragment shaders.
7202  *
7203  * @tparam API               Tested API descriptor
7204  *
7205  * @param tested_shader_type The type of shader that is being tested
7206  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7207  */
7208 template <class API>
7209 void InteractionStorageBuffers1<API>::test_shader_compilation(
7210         typename TestCaseBase<API>::TestShaderType tested_shader_type)
7211 {
7212         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7213         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7214
7215         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7216                                                                                                                          VAR_TYPE_DOUBLE };
7217         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7218
7219         const glcts::test_var_type* var_types_set = var_types_set_es;
7220         size_t                                          num_var_types = num_var_types_es;
7221
7222         if (API::USE_DOUBLE)
7223         {
7224                 var_types_set = var_types_set_gl;
7225                 num_var_types = num_var_types_gl;
7226         }
7227
7228         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7229         {
7230                 _supported_variable_types_map_const_iterator var_iterator =
7231                         supported_variable_types_map.find(var_types_set[var_type_index]);
7232
7233                 if (var_iterator != supported_variable_types_map.end())
7234                 {
7235                         std::string shader_source;
7236
7237                         shader_source += "buffer uBlocka {\n";
7238                         shader_source += "    " + var_iterator->second.type + " x[1][1][1][1][1][1];\n";
7239                         shader_source += "};\n\n";
7240                         shader_source += shader_start;
7241
7242                         /* End main */
7243                         DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7244
7245                         /* Execute test */
7246                         EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
7247                 } /* if var_type iterator found */
7248                 else
7249                 {
7250                         TCU_FAIL("Type not found.");
7251                 }
7252         }
7253 }
7254
7255 /* Generates the shader source code for the InteractionUniformBuffers2
7256  * array tests, and attempts to compile each test shader, for both
7257  * vertex and fragment shaders.
7258  *
7259  * @tparam API               Tested API descriptor
7260  *
7261  * @param tested_shader_type The type of shader that is being tested
7262  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7263  */
7264 template <class API>
7265 void InteractionStorageBuffers2<API>::test_shader_compilation(
7266         typename TestCaseBase<API>::TestShaderType tested_shader_type)
7267 {
7268         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7269         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7270
7271         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7272                                                                                                                          VAR_TYPE_DOUBLE };
7273         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7274
7275         const glw::Functions&           gl                        = this->context_id.getRenderContext().getFunctions();
7276         const glcts::test_var_type* var_types_set = var_types_set_es;
7277         size_t                                          num_var_types = num_var_types_es;
7278
7279         if (API::USE_DOUBLE)
7280         {
7281                 var_types_set = var_types_set_gl;
7282                 num_var_types = num_var_types_gl;
7283         }
7284
7285         /* Iterate through float / int / uint values. */
7286         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7287         {
7288                 _supported_variable_types_map_const_iterator var_iterator =
7289                         supported_variable_types_map.find(var_types_set[var_type_index]);
7290
7291                 if (var_iterator != supported_variable_types_map.end())
7292                 {
7293                         std::string uniform_definition;
7294                         std::string uniform_use;
7295
7296                         uniform_definition += "layout (std140) buffer storage_block_name\n"
7297                                                                   "{\n";
7298                         uniform_definition += "    ";
7299                         uniform_definition += var_iterator->second.type;
7300                         uniform_definition += " my_storage_1[1][1][1][1];\n"
7301                                                                   "};\n";
7302
7303                         uniform_use = "    float result = float(my_storage_1[0][0][0][0]);\n";
7304
7305                         if (API::USE_ALL_SHADER_STAGES)
7306                         {
7307                                 const std::string& compute_shader_source =
7308                                         this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use);
7309                                 const std::string& fragment_shader_source =
7310                                         this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
7311                                 const std::string& geometry_shader_source =
7312                                         this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use);
7313                                 const std::string& tess_ctrl_shader_source =
7314                                         this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use);
7315                                 const std::string& tess_eval_shader_source =
7316                                         this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use);
7317                                 const std::string& vertex_shader_source =
7318                                         this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
7319
7320                                 switch (tested_shader_type)
7321                                 {
7322                                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
7323                                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7324                                         this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
7325                                         break;
7326
7327                                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7328                                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7329                                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
7330                                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7331                                         this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
7332                                                                                                 geometry_shader_source, fragment_shader_source, compute_shader_source,
7333                                                                                                 false, false);
7334                                         break;
7335
7336                                 default:
7337                                         TCU_FAIL("Invalid enum");
7338                                         break;
7339                                 }
7340                         }
7341                         else
7342                         {
7343                                 const std::string& fragment_shader_source =
7344                                         this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
7345                                 const std::string& vertex_shader_source =
7346                                         this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
7347
7348                                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
7349                         }
7350
7351                         glw::GLuint buffer_object_id       = 0;
7352                         glw::GLint  my_storage_block_index = GL_INVALID_INDEX;
7353
7354                         gl.useProgram(this->program_object_id);
7355                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
7356
7357                         my_storage_block_index =
7358                                 gl.getProgramResourceIndex(this->program_object_id, GL_SHADER_STORAGE_BLOCK, "storage_block_name");
7359                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() failed.");
7360
7361                         if ((unsigned)my_storage_block_index == GL_INVALID_INDEX)
7362                         {
7363                                 TCU_FAIL("Uniform block not found or is considered as not active.");
7364                         }
7365
7366                         gl.genBuffers(1, &buffer_object_id);
7367                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed.");
7368
7369                         gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_object_id);
7370                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed.");
7371
7372                         switch (var_type_index)
7373                         {
7374                         case 0: //float type of uniform is considered
7375                         {
7376                                 glw::GLfloat buffer_data[] = { 0.0f, 1.0f, 2.0f,  3.0f,  4.0f,  5.0f,  6.0f,  7.0f,
7377                                                                                            8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f };
7378
7379                                 gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7380                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7381
7382                                 break;
7383                         }               /* float case */
7384                         case 1: //int type of uniform is considered
7385                         {
7386
7387                                 glw::GLint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
7388
7389                                 gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7390                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7391
7392                                 break;
7393                         }               /* int case */
7394                         case 2: //uint type of uniform is considered
7395                         {
7396                                 glw::GLuint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
7397
7398                                 gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7399                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7400
7401                                 break;
7402                         }               /* uint case */
7403                         case 3: //double type of uniform is considered
7404                         {
7405                                 glw::GLdouble buffer_data[] = { 0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,
7406                                                                                                 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 };
7407
7408                                 gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7409                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7410
7411                                 break;
7412                         } /* double case */
7413                         default:
7414                         {
7415                                 TCU_FAIL("Invalid variable-type index.");
7416
7417                                 break;
7418                         }
7419                         } /* switch (var_type_index) */
7420
7421                         gl.shaderStorageBlockBinding(this->program_object_id, my_storage_block_index, 0);
7422                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding() failed.");
7423
7424                         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer_object_id);
7425                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed.");
7426
7427                         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type)
7428                         {
7429                                 execute_draw_test(tested_shader_type);
7430                         }
7431                         else
7432                         {
7433                                 execute_dispatch_test();
7434                         }
7435
7436                         /* Deallocate any resources used. */
7437                         gl.deleteBuffers(1, &buffer_object_id);
7438                         this->delete_objects();
7439                 } /* if var_type iterator found */
7440                 else
7441                 {
7442                         TCU_FAIL("Type not found.");
7443                 }
7444         } /* for (int var_type_index = 0; ...) */
7445 }
7446
7447 /** Executes test for compute program
7448  *
7449  * @tparam API               Tested API descriptor
7450  **/
7451 template <class API>
7452 void InteractionStorageBuffers2<API>::execute_dispatch_test()
7453 {
7454         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7455
7456         gl.dispatchCompute(1, 1, 1);
7457         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7458 }
7459
7460 /** Executes test for draw program
7461  *
7462  * @tparam API               Tested API descriptor
7463  *
7464  * @param tested_shader_type The type of shader that is being tested
7465  **/
7466 template <class API>
7467 void InteractionStorageBuffers2<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type)
7468 {
7469         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7470
7471         glw::GLuint vao_id = 0;
7472
7473         gl.genVertexArrays(1, &vao_id);
7474         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
7475
7476         gl.bindVertexArray(vao_id);
7477         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
7478
7479         switch (tested_shader_type)
7480         {
7481         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7482         case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
7483         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7484                 gl.drawArrays(GL_POINTS, 0, 1);
7485                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7486                 break;
7487
7488         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
7489         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7490                 /* Tesselation patch set up */
7491                 gl.patchParameteri(GL_PATCH_VERTICES, 1);
7492                 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
7493
7494                 gl.drawArrays(GL_PATCHES, 0, 1);
7495                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7496                 break;
7497
7498         default:
7499                 TCU_FAIL("Invalid enum");
7500                 break;
7501         }
7502
7503         gl.deleteVertexArrays(1, &vao_id);
7504         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() failed.");
7505 }
7506
7507 /* Generates the shader source code for the InteractionUniformBuffers3
7508  * array tests, and attempts to compile each test shader, for both
7509  * vertex and fragment shaders.
7510  *
7511  * @tparam API               Tested API descriptor
7512  *
7513  * @param tested_shader_type The type of shader that is being tested
7514  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7515  */
7516 template <class API>
7517 void InteractionStorageBuffers3<API>::test_shader_compilation(
7518         typename TestCaseBase<API>::TestShaderType tested_shader_type)
7519 {
7520         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7521         static const size_t                               num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7522
7523         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7524                                                                                                                          VAR_TYPE_DOUBLE };
7525         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7526
7527         const std::string invalid_size_declarations[] = { "[2][2][2][]", "[2][2][][2]", "[2][][2][2]", "[][2][2][2]",
7528                                                                                                           "[2][2][][]",  "[2][][2][]",  "[][2][2][]",  "[2][][][2]",
7529                                                                                                           "[][2][][2]",  "[][][2][2]",  "[2][][][]",   "[][2][][]",
7530                                                                                                           "[][][2][]",   "[][][][2]",   "[][][][]" };
7531         const std::string array_initializers[] = { "float[2][2][2][2](float[2][2][2](float[2][2](float[2](1.0, 2.0),"
7532                                                                                            "float[2](3.0, 4.0)),"
7533                                                                                            "float[2][2](float[2](5.0, 6.0),"
7534                                                                                            "float[2](7.0, 8.0))),"
7535                                                                                            "float[2][2][2](float[2][2](float[2](1.1, 2.1),"
7536                                                                                            "float[2](3.1, 4.1)),"
7537                                                                                            "float[2][2](float[2](5.1, 6.1),"
7538                                                                                            "float[2](7.1, 8.1))));\n",
7539
7540                                                                                            "int[2][2][2][2](int[2][2][2](int[2][2](int[2]( 1,  2),"
7541                                                                                            "int[2]( 3,  4)),"
7542                                                                                            "int[2][2](int[2]( 5,  6),"
7543                                                                                            "int[2]( 7,  8))),"
7544                                                                                            "int[2][2][2](int[2][2](int[2](11, 12),"
7545                                                                                            "int[2](13, 14)),"
7546                                                                                            "int[2][2](int[2](15, 16),"
7547                                                                                            "int[2](17, 18))));\n",
7548
7549                                                                                            "uint[2][2][2][2](uint[2][2][2](uint[2][2](uint[2]( 1u,  2u),"
7550                                                                                            "uint[2]( 3u,  4u)),"
7551                                                                                            "uint[2][2](uint[2]( 5u,  6u),"
7552                                                                                            "uint[2]( 7u,  8u))),"
7553                                                                                            "uint[2][2][2](uint[2][2](uint[2](11u, 12u),"
7554                                                                                            "uint[2](13u, 14u)),"
7555                                                                                            "uint[2][2](uint[2](15u, 16u),"
7556                                                                                            "uint[2](17u, 18u))));\n",
7557
7558                                                                                            "double[2][2][2][2](double[2][2][2](double[2][2](double[2](1.0, 2.0),"
7559                                                                                            "double[2](3.0, 4.0)),"
7560                                                                                            "double[2][2](double[2](5.0, 6.0),"
7561                                                                                            "double[2](7.0, 8.0))),"
7562                                                                                            "double[2][2][2](double[2][2](double[2](1.1, 2.1),"
7563                                                                                            "double[2](3.1, 4.1)),"
7564                                                                                            "double[2][2](double[2](5.1, 6.1),"
7565                                                                                            "double[2](7.1, 8.1))));\n" };
7566         const glcts::test_var_type* var_types_set = var_types_set_es;
7567         size_t                                          num_var_types = num_var_types_es;
7568
7569         if (API::USE_DOUBLE)
7570         {
7571                 var_types_set = var_types_set_gl;
7572                 num_var_types = num_var_types_gl;
7573         }
7574
7575         /* Iterate through float/ int/ uint types.
7576          * Case: without initializer.
7577          */
7578         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7579         {
7580                 _supported_variable_types_map_const_iterator var_iterator =
7581                         supported_variable_types_map.find(var_types_set[var_type_index]);
7582
7583                 if (var_iterator != supported_variable_types_map.end())
7584                 {
7585                         for (size_t invalid_size_declarations_index = 0;
7586                                  invalid_size_declarations_index <
7587                                  sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7588                                  invalid_size_declarations_index++)
7589                         {
7590                                 std::string shader_source;
7591
7592                                 shader_source = "layout (std140) buffer MyStorage {\n";
7593                                 shader_source += "    " + var_iterator->second.type +
7594                                                                  invalid_size_declarations[invalid_size_declarations_index] + " my_variable;\n";
7595                                 shader_source += "};\n\n";
7596                                 shader_source += shader_start;
7597
7598                                 /* End main */
7599                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7600
7601                                 /* Execute test */
7602                                 EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && invalid_size_declarations_index == 3,
7603                                                                         tested_shader_type, shader_source);
7604                         } /* for (int invalid_size_declarations_index = 0; ...) */
7605                 }
7606                 else
7607                 {
7608                         TCU_FAIL("Type not found.");
7609                 }
7610         } /* for (int var_type_index = 0; ...) */
7611
7612         /* Iterate through float/ int/ uint types.
7613          * Case: with initializer.
7614          */
7615         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7616         {
7617                 _supported_variable_types_map_const_iterator var_iterator =
7618                         supported_variable_types_map.find(var_types_set[var_type_index]);
7619
7620                 if (var_iterator != supported_variable_types_map.end())
7621                 {
7622                         for (size_t invalid_size_declarations_index = 0;
7623                                  invalid_size_declarations_index <
7624                                  sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7625                                  invalid_size_declarations_index++)
7626                         {
7627                                 std::string shader_source;
7628
7629                                 shader_source = "layout (std140) buffer MyStorage {\n";
7630                                 shader_source += "    " + var_iterator->second.type +
7631                                                                  invalid_size_declarations[invalid_size_declarations_index] +
7632                                                                  " my_variable = " + array_initializers[var_type_index];
7633
7634                                 var_iterator->second.type + invalid_size_declarations[invalid_size_declarations_index] +
7635                                         " my_variable = " + array_initializers[var_type_index];
7636                                 shader_source += "};\n\n";
7637                                 shader_source += shader_start;
7638
7639                                 /* End main */
7640                                 DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7641
7642                                 /* Execute test */
7643                                 this->execute_negative_test(tested_shader_type, shader_source);
7644                         } /* for (int invalid_size_declarations_index = 0; ...) */
7645                 }        /* if var_type iterator found */
7646                 else
7647                 {
7648                         TCU_FAIL("Type not found.");
7649                 }
7650         } /* for (int var_type_index = 0; ...) */
7651 }
7652
7653 /* Generates the shader source code for the InteractionInterfaceArrays1
7654  * array test, and attempts to compile the test shader.
7655  *
7656  * @tparam API               Tested API descriptor
7657  *
7658  * @param tested_shader_type The type of shader that is being tested.
7659  */
7660 template <class API>
7661 void InteractionInterfaceArrays1<API>::test_shader_compilation(
7662         typename TestCaseBase<API>::TestShaderType tested_shader_type)
7663 {
7664         /* Shader source with invalid buffer (buffer cannot be of arrays of arrays type). */
7665         const std::string invalid_buffer_shader_source = "layout(std140) buffer MyBuffer\n"
7666                                                                                                          "{\n"
7667                                                                                                          "    float f;\n"
7668                                                                                                          "    int   i;\n"
7669                                                                                                          "    uint  ui;\n"
7670                                                                                                          "} myBuffers[2][2];\n\n"
7671                                                                                                          "void main()\n"
7672                                                                                                          "{\n";
7673
7674         /* Verify that buffer arrays of arrays type is rejected. */
7675         {
7676                 std::string source = invalid_buffer_shader_source;
7677
7678                 DEFAULT_MAIN_ENDING(tested_shader_type, source);
7679
7680                 EXECUTE_SHADER_TEST(API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS, tested_shader_type, source);
7681         }
7682 }
7683
7684 /* Generates the shader source code for the InteractionInterfaceArrays2
7685  * array test, and attempts to compile the test shader.
7686  *
7687  * @tparam API              Tested API descriptor
7688  *
7689  * @param input_shader_type The type of shader that is being tested.
7690  */
7691 template <class API>
7692 void InteractionInterfaceArrays2<API>::test_shader_compilation(
7693         typename TestCaseBase<API>::TestShaderType input_shader_type)
7694 {
7695         /* Shader source with invalid input (input cannot be of arrays of arrays type). */
7696         const std::string input_variable_shader_source[] = { "in  float inout_variable", "[2][2];\n"
7697                                                                                                                                                                          "out float result",
7698                                                                                                                  ";\n\n"
7699                                                                                                                  "void main()\n"
7700                                                                                                                  "{\n"
7701                                                                                                                  "    result",
7702                                                                                                                  " = inout_variable", "[0][0];\n" };
7703         /* Shader source with invalid output (output cannot be of arrays of arrays type). */
7704         const std::string output_variable_shader_source[] = { "out float inout_variable",
7705                                                                                                                   "[2][2];\n\n"
7706                                                                                                                   "void main()\n"
7707                                                                                                                   "{\n"
7708                                                                                                                   "    inout_variable",
7709                                                                                                                   "[0][0] = 0.0;\n"
7710                                                                                                                   "    inout_variable",
7711                                                                                                                   "[0][1] = 1.0;\n"
7712                                                                                                                   "    inout_variable",
7713                                                                                                                   "[1][0] = 2.0;\n"
7714                                                                                                                   "    inout_variable",
7715                                                                                                                   "[1][1] = 3.0;\n" };
7716
7717         const typename TestCaseBase<API>::TestShaderType& output_shader_type =
7718                 this->get_output_shader_type(input_shader_type);
7719         std::string input_source;
7720         std::string output_source;
7721
7722         this->prepare_sources(input_shader_type, output_shader_type, input_variable_shader_source,
7723                                                   output_variable_shader_source, input_source, output_source);
7724
7725         /* Verify that INPUTs and OUTPUTs arrays of arrays type is rejected. */
7726         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type)
7727         {
7728                 if (API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS)
7729                 {
7730
7731                         if (API::USE_ALL_SHADER_STAGES)
7732                         {
7733                                 const std::string& compute_shader_source = empty_string;
7734                                 const std::string& fragment_shader_source =
7735                                         this->prepare_fragment_shader(input_shader_type, input_source, output_source);
7736                                 const std::string& geometry_shader_source =
7737                                         this->prepare_geometry_shader(input_shader_type, input_source, output_source);
7738                                 const std::string& tess_ctrl_shader_source =
7739                                         this->prepare_tess_ctrl_shader_source(input_shader_type, input_source, output_source);
7740                                 const std::string& tess_eval_shader_source =
7741                                         this->prepare_tess_eval_shader_source(input_shader_type, input_source, output_source);
7742                                 const std::string& vertex_shader_source =
7743                                         this->prepare_vertex_shader(input_shader_type, input_source, output_source);
7744
7745                                 this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
7746                                                                                         geometry_shader_source, fragment_shader_source, compute_shader_source, true,
7747                                                                                         false);
7748                         }
7749                         else
7750                         {
7751                                 const std::string& fragment_shader_source =
7752                                         this->prepare_fragment_shader(input_shader_type, input_source, output_source);
7753                                 const std::string& vertex_shader_source =
7754                                         this->prepare_vertex_shader(input_shader_type, input_source, output_source);
7755
7756                                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, true, false);
7757                         }
7758                 }
7759                 else
7760                 {
7761                         this->execute_negative_test(input_shader_type, input_source);
7762                         this->execute_negative_test(output_shader_type, output_source);
7763                 }
7764         }
7765 }
7766
7767 /** Gets the shader type to test for the outputs
7768  *
7769  * @tparam API              Tested API descriptor
7770  *
7771  * @param input_shader_type The type of input shader that is being tested
7772  **/
7773 template <class API>
7774 const typename TestCaseBase<API>::TestShaderType InteractionInterfaceArrays2<API>::get_output_shader_type(
7775         const typename TestCaseBase<API>::TestShaderType& input_shader_type)
7776 {
7777         switch (input_shader_type)
7778         {
7779         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7780                 return TestCaseBase<API>::FRAGMENT_SHADER_TYPE;
7781
7782         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7783                 if (API::USE_ALL_SHADER_STAGES)
7784                 {
7785                         return TestCaseBase<API>::GEOMETRY_SHADER_TYPE;
7786                 }
7787                 else
7788                 {
7789                         return TestCaseBase<API>::VERTEX_SHADER_TYPE;
7790                 }
7791
7792         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7793                 break;
7794
7795         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7796                 return TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE;
7797
7798         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7799                 return TestCaseBase<API>::VERTEX_SHADER_TYPE;
7800
7801         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7802                 return TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE;
7803
7804         default:
7805                 TCU_FAIL("Unrecognized shader type.");
7806                 break;
7807         }
7808
7809         return input_shader_type;
7810 }
7811
7812 /** Prepare fragment shader
7813  *
7814  * @tparam API              Tested API descriptor
7815  *
7816  * @param input_shader_type The type of input shader that is being tested
7817  * @param input_source      Shader in case we want to test inputs for this shader
7818  * @param output_source     Shader in case we want to test outputs for this shader
7819  **/
7820 template <class API>
7821 const std::string InteractionInterfaceArrays2<API>::prepare_fragment_shader(
7822         const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7823         const std::string& output_source)
7824 {
7825         switch (input_shader_type)
7826         {
7827         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7828                 return output_source;
7829
7830         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7831                 return input_source;
7832
7833         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7834         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7835         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7836         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7837                 break;
7838
7839         default:
7840                 TCU_FAIL("Unrecognized shader type.");
7841                 break;
7842         }
7843
7844         return default_fragment_shader_source;
7845 }
7846
7847 /** Prepare geometry shader
7848  *
7849  * @tparam API              Tested API descriptor
7850  *
7851  * @param input_shader_type The type of input shader that is being tested
7852  * @param input_source      Shader in case we want to test inputs for this shader
7853  * @param output_source     Shader in case we want to test outputs for this shader
7854  **/
7855 template <class API>
7856 const std::string InteractionInterfaceArrays2<API>::prepare_geometry_shader(
7857         const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7858         const std::string& output_source)
7859 {
7860         switch (input_shader_type)
7861         {
7862         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7863                 if (API::USE_ALL_SHADER_STAGES)
7864                 {
7865                         return output_source;
7866                 }
7867                 break;
7868
7869         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7870                 return input_source;
7871
7872         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7873         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7874         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7875         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7876                 break;
7877
7878         default:
7879                 TCU_FAIL("Unrecognized shader type.");
7880                 break;
7881         }
7882
7883         return default_geometry_shader_source;
7884 }
7885
7886 /** Prepare tessellation control shader
7887  *
7888  * @tparam API              Tested API descriptor
7889  *
7890  * @param input_shader_type The type of input shader that is being tested
7891  * @param input_source      Shader in case we want to test inputs for this shader
7892  * @param output_source     Shader in case we want to test outputs for this shader
7893  **/
7894 template <class API>
7895 const std::string InteractionInterfaceArrays2<API>::prepare_tess_ctrl_shader_source(
7896         const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7897         const std::string& output_source)
7898 {
7899         switch (input_shader_type)
7900         {
7901         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7902         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7903         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7904         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7905                 break;
7906
7907         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7908                 return input_source;
7909
7910         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7911                 return output_source;
7912
7913         default:
7914                 TCU_FAIL("Unrecognized shader type.");
7915                 break;
7916         }
7917
7918         return default_tc_shader_source;
7919 }
7920
7921 /** Prepare tessellation evaluation shader
7922  *
7923  * @tparam API              Tested API descriptor
7924  *
7925  * @param input_shader_type The type of input shader that is being tested
7926  * @param input_source      Shader in case we want to test inputs for this shader
7927  * @param output_source     Shader in case we want to test outputs for this shader
7928  **/
7929 template <class API>
7930 const std::string InteractionInterfaceArrays2<API>::prepare_tess_eval_shader_source(
7931         const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7932         const std::string& output_source)
7933 {
7934         switch (input_shader_type)
7935         {
7936         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7937         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7938         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7939         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7940                 break;
7941
7942         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7943                 return output_source;
7944
7945         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7946                 return input_source;
7947
7948         default:
7949                 TCU_FAIL("Unrecognized shader type.");
7950                 break;
7951         }
7952
7953         return default_te_shader_source;
7954 }
7955
7956 /** Prepare vertex shader
7957  *
7958  * @tparam API              Tested API descriptor
7959  *
7960  * @param input_shader_type The type of input shader that is being tested
7961  * @param input_source      Shader in case we want to test inputs for this shader
7962  * @param output_source     Shader in case we want to test outputs for this shader
7963  **/
7964 template <class API>
7965 const std::string InteractionInterfaceArrays2<API>::prepare_vertex_shader(
7966         const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7967         const std::string& output_source)
7968 {
7969         switch (input_shader_type)
7970         {
7971         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7972                 return input_source;
7973
7974         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7975                 if (!API::USE_ALL_SHADER_STAGES)
7976                 {
7977                         return output_source;
7978                 }
7979                 break;
7980
7981         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7982                 return output_source;
7983
7984         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7985         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7986         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7987                 break;
7988
7989         default:
7990                 TCU_FAIL("Unrecognized shader type.");
7991                 break;
7992         }
7993
7994         return default_vertex_shader_source;
7995 }
7996
7997 /** Prepare the inputs and outputs shaders
7998  *
7999  * @tparam API                 Tested API descriptor
8000  *
8001  * @param input_shader_type    The type of input shader that is being tested
8002  * @param output_shader_type   The type of output shader that is being tested
8003  * @param input_shader_source  Snippet used to prepare the input shader
8004  * @param output_shader_source Snippet used to prepare the output shader
8005  * @param input_source         Resulting input shader
8006  * @param output_source        Resulting output shader
8007  **/
8008 template <class API>
8009 void InteractionInterfaceArrays2<API>::prepare_sources(
8010         const typename TestCaseBase<API>::TestShaderType& input_shader_type,
8011         const typename TestCaseBase<API>::TestShaderType& output_shader_type, const std::string* input_shader_source,
8012         const std::string* output_shader_source, std::string& input_source, std::string& output_source)
8013 {
8014         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type)
8015         {
8016                 input_source += input_shader_source[0];
8017                 output_source += output_shader_source[0];
8018
8019                 if ((TestCaseBase<API>::GEOMETRY_SHADER_TYPE == input_shader_type) ||
8020                         (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type) ||
8021                         (TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE == input_shader_type))
8022                 {
8023                         input_source += "[]";
8024                 }
8025
8026                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8027                 {
8028                         output_source += "[]";
8029                 }
8030
8031                 input_source += input_shader_source[1];
8032                 output_source += output_shader_source[1];
8033
8034                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type)
8035                 {
8036                         input_source += "[]";
8037                 }
8038
8039                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8040                 {
8041                         output_source += "[gl_InvocationID]";
8042                 }
8043
8044                 input_source += input_shader_source[2];
8045                 output_source += output_shader_source[2];
8046
8047                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type)
8048                 {
8049                         input_source += "[gl_InvocationID]";
8050                 }
8051
8052                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8053                 {
8054                         output_source += "[gl_InvocationID]";
8055                 }
8056
8057                 input_source += input_shader_source[3];
8058                 output_source += output_shader_source[3];
8059
8060                 if ((TestCaseBase<API>::GEOMETRY_SHADER_TYPE == input_shader_type) ||
8061                         (TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE == input_shader_type))
8062                 {
8063                         input_source += "[0]";
8064                 }
8065
8066                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type)
8067                 {
8068                         input_source += "[gl_InvocationID]";
8069                 }
8070
8071                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8072                 {
8073                         output_source += "[gl_InvocationID]";
8074                 }
8075
8076                 input_source += input_shader_source[4];
8077                 output_source += output_shader_source[4];
8078
8079                 if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8080                 {
8081                         output_source += "[gl_InvocationID]";
8082                 }
8083
8084                 output_source += output_shader_source[5];
8085
8086                 DEFAULT_MAIN_ENDING(input_shader_type, input_source);
8087                 DEFAULT_MAIN_ENDING(output_shader_type, output_source);
8088         }
8089 }
8090
8091 /* Generates the shader source code for the InteractionInterfaceArrays3
8092  * array test, and attempts to compile the test shader.
8093  *
8094  * @tparam API               Tested API descriptor
8095  *
8096  * @param tested_shader_type The type of shader that is being tested.
8097  */
8098 template <class API>
8099 void InteractionInterfaceArrays3<API>::test_shader_compilation(
8100         typename TestCaseBase<API>::TestShaderType tested_shader_type)
8101 {
8102         /* Shader source with invalid uniform block (uniform block cannot be of arrays of arrays type). */
8103         const std::string invalid_uniform_block_shader_source = "layout(std140) uniform MyUniformBlock\n"
8104                                                                                                                         "{\n"
8105                                                                                                                         "    float f;\n"
8106                                                                                                                         "    int   i;\n"
8107                                                                                                                         "    uint  ui;\n"
8108                                                                                                                         "} myUniformBlocks[2][2];\n\n"
8109                                                                                                                         "void main()\n"
8110                                                                                                                         "{\n";
8111
8112         /* Verify that uniform block arrays of arrays type is rejected. */
8113         {
8114                 std::string source = invalid_uniform_block_shader_source;
8115
8116                 DEFAULT_MAIN_ENDING(tested_shader_type, source);
8117
8118                 EXECUTE_SHADER_TEST(API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS, tested_shader_type, source);
8119         }
8120 }
8121
8122 /* Generates the shader source code for the InteractionInterfaceArrays4
8123  * array test, and attempts to compile the test shader.
8124  *
8125  * @tparam API              Tested API descriptor
8126  *
8127  * @param input_shader_type The type of shader that is being tested.
8128  */
8129 template <class API>
8130 void InteractionInterfaceArrays4<API>::test_shader_compilation(
8131         typename TestCaseBase<API>::TestShaderType input_shader_type)
8132 {
8133         /* Shader source with invalid input (input cannot be of arrays of arrays type). */
8134         const std::string input_block_shader_source[] = { "in  InOutBlock {\n"
8135                                                                                                           "    float inout_variable;\n"
8136                                                                                                           "} inout_block",
8137                                                                                                           "[2][2];\n"
8138                                                                                                           "out float result",
8139                                                                                                           ";\n\n"
8140                                                                                                           "void main()\n"
8141                                                                                                           "{\n"
8142                                                                                                           "    result",
8143                                                                                                           " = inout_block", "[0][0].inout_variable;\n" };
8144         /* Shader source with invalid output (output cannot be of arrays of arrays type). */
8145         const std::string output_block_shader_source[] = { "out InOutBlock {\n"
8146                                                                                                            "    float inout_variable;\n"
8147                                                                                                            "} inout_block",
8148                                                                                                            "[2][2];\n"
8149                                                                                                            "\n"
8150                                                                                                            "void main()\n"
8151                                                                                                            "{\n"
8152                                                                                                            "    inout_block",
8153                                                                                                            "[0][0].inout_variable = 0.0;\n"
8154                                                                                                            "    inout_block",
8155                                                                                                            "[0][1].inout_variable = 1.0;\n"
8156                                                                                                            "    inout_block",
8157                                                                                                            "[1][0].inout_variable = 2.0;\n"
8158                                                                                                            "    inout_block",
8159                                                                                                            "[1][1].inout_variable = 3.0;\n" };
8160
8161         const typename TestCaseBase<API>::TestShaderType& output_shader_type =
8162                 this->get_output_shader_type(input_shader_type);
8163         std::string input_source;
8164         std::string output_source;
8165
8166         this->prepare_sources(input_shader_type, output_shader_type, input_block_shader_source, output_block_shader_source,
8167                                                   input_source, output_source);
8168
8169         /* Verify that INPUTs and OUTPUTs arrays of arrays type is rejected. */
8170         if ((TestCaseBase<API>::VERTEX_SHADER_TYPE != input_shader_type) &&
8171                 (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type))
8172         {
8173                 if (API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS && API::ALLOW_IN_OUT_INTERFACE_BLOCKS)
8174                 {
8175
8176                         if (API::USE_ALL_SHADER_STAGES)
8177                         {
8178                                 const std::string& compute_shader_source = empty_string;
8179                                 const std::string& fragment_shader_source =
8180                                         this->prepare_fragment_shader(input_shader_type, input_source, output_source);
8181                                 const std::string& geometry_shader_source =
8182                                         this->prepare_geometry_shader(input_shader_type, input_source, output_source);
8183                                 const std::string& tess_ctrl_shader_source =
8184                                         this->prepare_tess_ctrl_shader_source(input_shader_type, input_source, output_source);
8185                                 const std::string& tess_eval_shader_source =
8186                                         this->prepare_tess_eval_shader_source(input_shader_type, input_source, output_source);
8187                                 const std::string& vertex_shader_source =
8188                                         this->prepare_vertex_shader(input_shader_type, input_source, output_source);
8189
8190                                 this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
8191                                                                                         geometry_shader_source, fragment_shader_source, compute_shader_source, true,
8192                                                                                         false);
8193                         }
8194                         else
8195                         {
8196                                 const std::string& fragment_shader_source =
8197                                         this->prepare_fragment_shader(input_shader_type, input_source, output_source);
8198                                 const std::string& vertex_shader_source =
8199                                         this->prepare_vertex_shader(input_shader_type, input_source, output_source);
8200
8201                                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, true, false);
8202                         }
8203                 }
8204                 else
8205                 {
8206                         this->execute_negative_test(input_shader_type, input_source);
8207                         this->execute_negative_test(output_shader_type, output_source);
8208                 }
8209         }
8210 }
8211
8212 /** Calulate smallest denominator for values over 1
8213  *
8214  * @param value Value in question
8215  *
8216  * @return Smallest denominator
8217  **/
8218 size_t findSmallestDenominator(const size_t value)
8219 {
8220         /* Skip 0 and 1 */
8221         for (size_t i = 2; i < value; ++i)
8222         {
8223                 if (0 == value % i)
8224                 {
8225                         return i;
8226                 }
8227         }
8228
8229         return value;
8230 }
8231
8232 /** Check if left is bigger than right
8233  *
8234  * @tparam T Type of values
8235
8236  * @param l  Left value
8237  * @param r  Right value
8238  *
8239  * @return true if l > r, false otherwise
8240  **/
8241 template <class T>
8242 bool more(const T& l, const T& r)
8243 {
8244         return l > r;
8245 }
8246
8247 /** Prepare dimensions of array with given number of entries
8248  *
8249  * @tparam API       Tested API descriptor
8250  *
8251  * @param n_entries  Number of entries
8252  * @param dimensions Storage for dimesnions
8253  **/
8254 template <class API>
8255 void prepareDimensions(size_t n_entries, std::vector<size_t>& dimensions)
8256 {
8257         if (dimensions.empty())
8258                 return;
8259
8260         const size_t last = dimensions.size() - 1;
8261
8262         /* Calculate */
8263         for (size_t i = 0; i < last; ++i)
8264         {
8265                 const size_t denom = findSmallestDenominator(n_entries);
8266
8267                 n_entries /= denom;
8268
8269                 dimensions[i] = denom;
8270         }
8271
8272         dimensions[last] = n_entries;
8273
8274         /* Sort */
8275         std::sort(dimensions.begin(), dimensions.end(), more<size_t>);
8276 }
8277
8278 /* Generates the shader source code for the AtomicDeclarationTest
8279  * and attempts to compile each shader
8280  *
8281  * @tparam API               Tested API descriptor
8282  *
8283  * @param tested_shader_type The type of shader that is being tested
8284  */
8285 template <class API>
8286 void AtomicDeclarationTest<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
8287 {
8288         static const char* indent_step             = "    ";
8289         static const char* uniform_atomic_uint = "layout(binding = 0) uniform atomic_uint";
8290
8291         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
8292
8293         std::string                     comment;
8294         std::vector<size_t> dimensions;
8295         std::string                     indent;
8296         std::string                     indexing;
8297         std::string                     invalid_definition = uniform_atomic_uint;
8298         std::string                     invalid_iteration;
8299         std::string                     invalid_shader_source;
8300         std::string                     loop_end;
8301         glw::GLint                      max_atomics = 0;
8302         glw::GLenum                     pname           = 0;
8303         std::string                     valid_shader_source;
8304         std::string                     valid_definition = uniform_atomic_uint;
8305         std::string                     valid_iteration;
8306
8307         /* Select pname of max for stage */
8308         switch (tested_shader_type)
8309         {
8310         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8311                 pname = GL_MAX_COMPUTE_ATOMIC_COUNTERS;
8312                 break;
8313         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8314                 pname = GL_MAX_FRAGMENT_ATOMIC_COUNTERS;
8315                 break;
8316         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8317                 pname = GL_MAX_GEOMETRY_ATOMIC_COUNTERS;
8318                 break;
8319         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8320                 pname = GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS;
8321                 break;
8322         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8323                 pname = GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS;
8324                 break;
8325         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8326                 pname = GL_MAX_VERTEX_ATOMIC_COUNTERS;
8327                 break;
8328         default:
8329                 TCU_FAIL("Invalid enum");
8330                 break;
8331         }
8332
8333         /* Get maximum */
8334         gl.getIntegerv(pname, &max_atomics);
8335         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8336
8337         if (0 == max_atomics)
8338         {
8339                 /* Not supported - skip */
8340                 return;
8341         }
8342         else
8343         {
8344                 dimensions.resize(API::MAX_ARRAY_DIMENSIONS);
8345                 prepareDimensions<API>(max_atomics, dimensions);
8346         }
8347
8348         /* Prepare parts of shader */
8349         for (size_t i = API::MAX_ARRAY_DIMENSIONS; i != 0; --i)
8350         {
8351                 char it[16];
8352                 char max[16];
8353
8354                 indent += indent_step;
8355
8356                 loop_end.insert(0, "}\n");
8357                 loop_end.insert(0, indent);
8358
8359                 sprintf(it, "i%u", (unsigned int)(API::MAX_ARRAY_DIMENSIONS - i));
8360
8361                 indexing += "[";
8362                 indexing += it;
8363                 indexing += "]";
8364
8365                 sprintf(max, "%u", (unsigned int)(dimensions[i - 1]));
8366
8367                 valid_definition += "[";
8368                 valid_definition += max;
8369                 valid_definition += "]";
8370
8371                 valid_iteration += indent;
8372                 valid_iteration += "for (uint ";
8373                 valid_iteration += it;
8374                 valid_iteration += " = 0; ";
8375                 valid_iteration += it;
8376                 valid_iteration += " < ";
8377                 valid_iteration += max;
8378                 valid_iteration += "; ++";
8379                 valid_iteration += it;
8380                 valid_iteration += ")\n";
8381                 valid_iteration += indent;
8382                 valid_iteration += "{\n";
8383
8384                 if (1 == i)
8385                 {
8386                         sprintf(max, "%u", (unsigned int)(dimensions[i - 1] + 1));
8387                 }
8388                 invalid_definition += "[";
8389                 invalid_definition += max;
8390                 invalid_definition += "]";
8391
8392                 invalid_iteration += indent;
8393                 invalid_iteration += "for (uint ";
8394                 invalid_iteration += it;
8395                 invalid_iteration += " = 0; ";
8396                 invalid_iteration += it;
8397                 invalid_iteration += " < ";
8398                 invalid_iteration += max;
8399                 invalid_iteration += "; ++";
8400                 invalid_iteration += it;
8401                 invalid_iteration += ")\n";
8402                 invalid_iteration += indent;
8403                 invalid_iteration += "{\n";
8404         }
8405
8406         {
8407                 char max[16];
8408
8409                 sprintf(max, "%u", (unsigned int)(max_atomics));
8410                 comment += "/* MAX_*_ATOMIC_COUNTERS = ";
8411                 comment += max;
8412                 comment += " */\n";
8413         }
8414
8415         /* Prepare invalid source */
8416         invalid_shader_source += comment;
8417         invalid_shader_source += invalid_definition;
8418         invalid_shader_source += " a;\n\nvoid main()\n{\n";
8419         invalid_shader_source += invalid_iteration;
8420         invalid_shader_source += indent;
8421         invalid_shader_source += indent_step;
8422         invalid_shader_source += "atomicCounterIncrement( a";
8423         invalid_shader_source += indexing;
8424         invalid_shader_source += " );\n";
8425         invalid_shader_source += loop_end;
8426
8427         /* Prepare valid source */
8428         valid_shader_source += comment;
8429         valid_shader_source += valid_definition;
8430         valid_shader_source += " a;\n\nvoid main()\n{\n";
8431         valid_shader_source += valid_iteration;
8432         valid_shader_source += indent;
8433         valid_shader_source += indent_step;
8434         valid_shader_source += "atomicCounterIncrement( a";
8435         valid_shader_source += indexing;
8436         valid_shader_source += " );\n";
8437         valid_shader_source += loop_end;
8438
8439         /* End main */
8440         DEFAULT_MAIN_ENDING(tested_shader_type, invalid_shader_source);
8441         DEFAULT_MAIN_ENDING(tested_shader_type, valid_shader_source);
8442
8443         /* Execute test */
8444         EXECUTE_POSITIVE_TEST(tested_shader_type, valid_shader_source, true, false);
8445
8446         /* Expect build failure for invalid shader source */
8447         {
8448                 bool negative_build_test_result = false;
8449
8450                 try
8451                 {
8452                         EXECUTE_POSITIVE_TEST(tested_shader_type, invalid_shader_source, true, false);
8453                 }
8454                 catch (...)
8455                 {
8456                         negative_build_test_result = true;
8457                 }
8458
8459                 if (false == negative_build_test_result)
8460                 {
8461                         TCU_FAIL("It was expected that build process will fail");
8462                 }
8463         }
8464 }
8465
8466 /* Generates the shader source code for the AtomicUsageTest
8467  * and attempts to compile each shader
8468  *
8469  * @tparam API               Tested API descriptor
8470  *
8471  * @param tested_shader_type The type of shader that is being tested
8472  */
8473 template <class API>
8474 void AtomicUsageTest<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
8475 {
8476         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
8477
8478         glw::GLint  max_atomics  = 0;
8479         glw::GLint  max_bindings = 0;
8480         glw::GLint  max_size     = 0;
8481         glw::GLenum pname                = 0;
8482
8483         /* Select pname of max for stage */
8484         switch (tested_shader_type)
8485         {
8486         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8487                 pname = GL_MAX_COMPUTE_ATOMIC_COUNTERS;
8488                 break;
8489         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8490                 pname = GL_MAX_FRAGMENT_ATOMIC_COUNTERS;
8491                 break;
8492         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8493                 pname = GL_MAX_GEOMETRY_ATOMIC_COUNTERS;
8494                 break;
8495         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8496                 pname = GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS;
8497                 break;
8498         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8499                 pname = GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS;
8500                 break;
8501         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8502                 pname = GL_MAX_VERTEX_ATOMIC_COUNTERS;
8503                 break;
8504         default:
8505                 TCU_FAIL("Invalid enum");
8506                 break;
8507         }
8508
8509         /* Get limits */
8510         gl.getIntegerv(pname, &max_atomics);
8511         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8512
8513         gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings);
8514         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8515
8516         gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, &max_size);
8517         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8518
8519         if (0 == max_atomics)
8520         {
8521                 /* Not supported - skip */
8522                 return;
8523         }
8524
8525         const glw::GLuint last_binding = (glw::GLuint)max_bindings - 1;
8526         const glw::GLuint offset           = (glw::GLuint)max_size / 2;
8527         glw::GLuint               n_entries =
8528                 std::min((glw::GLuint)(max_size - offset) / (glw::GLuint)sizeof(glw::GLuint), (glw::GLuint)max_atomics);
8529
8530         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
8531         {
8532                 glw::GLint max_uniform_locations = 0;
8533
8534                 gl.getIntegerv(GL_MAX_UNIFORM_LOCATIONS, &max_uniform_locations);
8535                 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8536
8537                 max_atomics = std::min(max_atomics, (max_uniform_locations - 1));
8538                 n_entries   = (glw::GLuint)std::min((glw::GLint)n_entries, (max_uniform_locations - 1));
8539         }
8540
8541         execute(tested_shader_type, last_binding, 0 /* offset */, max_atomics);
8542         execute(tested_shader_type, last_binding, offset, n_entries);
8543 }
8544
8545 /* Generates the shader source code for the AtomicUsageTest
8546  * and attempts to compile each shader
8547  *
8548  * @tparam API               Tested API descriptor
8549  *
8550  * @param tested_shader_type The type of shader that is being tested
8551  * @param binding            Binding index
8552  * @param offset             Offset of data
8553  * @param n_entries          Number of entries in array
8554  */
8555 template <class API>
8556 void AtomicUsageTest<API>::execute(typename TestCaseBase<API>::TestShaderType tested_shader_type, glw::GLuint binding,
8557                                                                    glw::GLuint offset, glw::GLuint n_entries)
8558 {
8559         static const char* indent_step             = "    ";
8560         static const char* layout_binding         = "layout(binding = ";
8561         static const char* layout_offset           = ", offset = ";
8562         static const char* uniform_atomic_uint = ") uniform atomic_uint";
8563
8564         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
8565
8566         std::string                     comment;
8567         std::vector<size_t> dimensions;
8568         std::string                     indent;
8569         std::string                     indexing;
8570         std::string                     loop_end;
8571         std::string                     result;
8572         std::string                     valid_shader_source;
8573         std::string                     valid_definition = layout_binding;
8574         std::string                     valid_iteration;
8575         std::string                     varying_definition;
8576
8577         dimensions.resize(API::MAX_ARRAY_DIMENSIONS);
8578         prepareDimensions<API>(n_entries, dimensions);
8579
8580         /* Prepare parts of shader */
8581
8582         /* Append binding */
8583         {
8584                 char buffer[16];
8585                 sprintf(buffer, "%u", static_cast<unsigned int>(binding));
8586                 valid_definition += buffer;
8587                 valid_definition += layout_offset;
8588                 sprintf(buffer, "%u", static_cast<unsigned int>(offset));
8589                 valid_definition += buffer;
8590                 valid_definition += uniform_atomic_uint;
8591         }
8592
8593         for (size_t i = API::MAX_ARRAY_DIMENSIONS; i != 0; --i)
8594         {
8595                 char it[16];
8596                 char max[16];
8597
8598                 indent += indent_step;
8599
8600                 loop_end.insert(0, "}\n");
8601                 loop_end.insert(0, indent);
8602
8603                 sprintf(it, "i%u", (unsigned int)(API::MAX_ARRAY_DIMENSIONS - i));
8604
8605                 indexing += "[";
8606                 indexing += it;
8607                 indexing += "]";
8608
8609                 sprintf(max, "%u", (unsigned int)(dimensions[i - 1]));
8610                 valid_definition += "[";
8611                 valid_definition += max;
8612                 valid_definition += "]";
8613
8614                 valid_iteration += indent;
8615                 valid_iteration += "for (uint ";
8616                 valid_iteration += it;
8617                 valid_iteration += " = 0; ";
8618                 valid_iteration += it;
8619                 valid_iteration += " < ";
8620                 valid_iteration += max;
8621                 valid_iteration += "; ++";
8622                 valid_iteration += it;
8623                 valid_iteration += ")\n";
8624                 valid_iteration += indent;
8625                 valid_iteration += "{\n";
8626         }
8627
8628         {
8629                 char max[16];
8630
8631                 sprintf(max, "%u", (unsigned int)(n_entries));
8632                 comment += "/* Number of atomic counters = ";
8633                 comment += max;
8634                 comment += " */\n";
8635         }
8636
8637         /* Select varyings and result */
8638         switch (tested_shader_type)
8639         {
8640         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8641                 result                     = "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n";
8642                 varying_definition = "writeonly uniform image2D uni_image;\n"
8643                                                          "\n";
8644                 break;
8645
8646         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8647                 result                     = "    color = vec4(result);\n";
8648                 varying_definition = "out vec4 color;\n"
8649                                                          "\n";
8650                 break;
8651
8652         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8653                 result = "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8654                                  "    fs_result = result;\n"
8655                                  "    EmitVertex();\n"
8656                                  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8657                                  "    fs_result = result;\n"
8658                                  "    EmitVertex();\n"
8659                                  "    gl_Position  = vec4(1, -1, 0, 1);\n"
8660                                  "    fs_result = result;\n"
8661                                  "    EmitVertex();\n"
8662                                  "    gl_Position  = vec4(1, 1, 0, 1);\n"
8663                                  "    fs_result = result;\n"
8664                                  "    EmitVertex();\n";
8665                 varying_definition = "out float fs_result;\n"
8666                                                          "\n";
8667                 break;
8668
8669         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8670                 result = "    tcs_result[gl_InvocationID] = result;\n"
8671                                  "\n"
8672                                  "    gl_TessLevelOuter[0] = 1.0;\n"
8673                                  "    gl_TessLevelOuter[1] = 1.0;\n"
8674                                  "    gl_TessLevelOuter[2] = 1.0;\n"
8675                                  "    gl_TessLevelOuter[3] = 1.0;\n"
8676                                  "    gl_TessLevelInner[0] = 1.0;\n"
8677                                  "    gl_TessLevelInner[1] = 1.0;\n";
8678                 varying_definition = "out float tcs_result[];\n"
8679                                                          "\n";
8680                 break;
8681
8682         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8683                 result                     = "    fs_result = result;\n";
8684                 varying_definition = "out float fs_result;\n"
8685                                                          "\n";
8686                 break;
8687
8688         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8689                 result                     = "    fs_result = result;\n";
8690                 varying_definition = "out float fs_result;\n"
8691                                                          "\n";
8692                 break;
8693
8694         default:
8695                 TCU_FAIL("Invalid enum");
8696                 break;
8697         };
8698
8699         /* Prepare valid source */
8700         valid_shader_source += varying_definition;
8701         valid_shader_source += comment;
8702         valid_shader_source += valid_definition;
8703         valid_shader_source += " a;\n\nvoid main()\n{\n    uint sum = 0u;\n";
8704         valid_shader_source += valid_iteration;
8705         valid_shader_source += indent;
8706         valid_shader_source += indent_step;
8707         valid_shader_source += "sum += atomicCounterIncrement( a";
8708         valid_shader_source += indexing;
8709         valid_shader_source += " );\n";
8710         valid_shader_source += loop_end;
8711         valid_shader_source += "\n"
8712                                                    "    float result = 0.0;\n"
8713                                                    "\n"
8714                                                    "    if (16u < sum)\n"
8715                                                    "    {\n"
8716                                                    "         result = 1.0;\n"
8717                                                    "    }\n";
8718         valid_shader_source += result;
8719         valid_shader_source += shader_end;
8720
8721         /* Build program */
8722         {
8723                 const std::string* cs  = &empty_string;
8724                 const std::string* vs  = &default_vertex_shader_source;
8725                 const std::string* tcs = &empty_string;
8726                 const std::string* tes = &empty_string;
8727                 const std::string* gs  = &empty_string;
8728                 const std::string* fs  = &pass_fragment_shader_source;
8729
8730                 switch (tested_shader_type)
8731                 {
8732                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8733                         cs = &valid_shader_source;
8734                         vs = &empty_string;
8735                         fs = &empty_string;
8736                         break;
8737
8738                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8739                         fs = &valid_shader_source;
8740                         break;
8741
8742                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8743                         gs = &valid_shader_source;
8744                         break;
8745
8746                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8747                         tcs = &valid_shader_source;
8748                         tes = &pass_te_shader_source;
8749                         break;
8750
8751                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8752                         tcs = &default_tc_shader_source;
8753                         tes = &valid_shader_source;
8754                         break;
8755
8756                 case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8757                         vs = &valid_shader_source;
8758                         break;
8759
8760                 default:
8761                         TCU_FAIL("Invalid enum");
8762                         break;
8763                 };
8764
8765                 if (API::USE_ALL_SHADER_STAGES)
8766                 {
8767                         this->execute_positive_test(*vs, *tcs, *tes, *gs, *fs, *cs, false, false);
8768                 }
8769                 else
8770                 {
8771                         this->execute_positive_test(*vs, *fs, false, false);
8772                 }
8773         }
8774
8775         gl.useProgram(this->program_object_id);
8776         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
8777
8778         /* Prepare buffer */
8779         glw::GLuint                              buffer_object_id = 0;
8780         std::vector<glw::GLuint> buffer_data;
8781         const size_t                     start_pos                = offset / 4;
8782         const size_t                     last_pos                 = start_pos + n_entries;
8783         const size_t                     buffer_data_size = last_pos * sizeof(glw::GLuint);
8784
8785         gl.genBuffers(1, &buffer_object_id);
8786         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed.");
8787
8788         gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer_object_id);
8789         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed.");
8790
8791         buffer_data.resize(start_pos + n_entries);
8792         for (size_t i = 0; i < n_entries; ++i)
8793         {
8794                 buffer_data[start_pos + i] = (glw::GLuint)i;
8795         }
8796
8797         gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, buffer_data_size, &buffer_data[0], GL_STATIC_DRAW);
8798         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
8799
8800         gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, binding, buffer_object_id);
8801         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed.");
8802
8803         /* Run program */
8804         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type)
8805         {
8806                 glw::GLuint framebuffer_object_id = 0;
8807                 glw::GLuint texture_object_id    = 0;
8808                 glw::GLuint vao_id                                = 0;
8809
8810                 gl.genTextures(1, &texture_object_id);
8811                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
8812
8813                 gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
8814                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
8815
8816                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
8817                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
8818
8819                 gl.genFramebuffers(1, &framebuffer_object_id);
8820                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
8821
8822                 gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
8823                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
8824
8825                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
8826                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
8827
8828                 gl.viewport(0, 0, 1, 1);
8829                 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
8830
8831                 gl.genVertexArrays(1, &vao_id);
8832                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
8833
8834                 gl.bindVertexArray(vao_id);
8835                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
8836
8837                 switch (tested_shader_type)
8838                 {
8839                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8840                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
8841                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8842                         gl.drawArrays(GL_POINTS, 0, 1);
8843                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
8844                         break;
8845
8846                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
8847                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8848                         /* Tesselation patch set up */
8849                         gl.patchParameteri(GL_PATCH_VERTICES, 1);
8850                         GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
8851
8852                         gl.drawArrays(GL_PATCHES, 0, 1);
8853                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
8854                         break;
8855
8856                 default:
8857                         TCU_FAIL("Invalid enum");
8858                         break;
8859                 }
8860
8861                 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
8862                 GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier.");
8863
8864                 gl.bindTexture(GL_TEXTURE_2D, 0);
8865                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
8866                 gl.bindVertexArray(0);
8867                 gl.deleteTextures(1, &texture_object_id);
8868                 gl.deleteFramebuffers(1, &framebuffer_object_id);
8869                 gl.deleteVertexArrays(1, &vao_id);
8870                 GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
8871         }
8872         else
8873         {
8874                 gl.dispatchCompute(1, 1, 1);
8875                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
8876
8877                 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
8878                 GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier.");
8879         }
8880
8881         /* Verify results */
8882         bool test_result = true;
8883
8884         const glw::GLuint* results =
8885                 (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /* offset */, buffer_data_size, GL_MAP_READ_BIT);
8886         GLU_EXPECT_NO_ERROR(gl.getError(), "MapBufferRange");
8887
8888         /* Anything before start position should be 0 */
8889         for (size_t i = 0; i < start_pos; ++i)
8890         {
8891                 if (0 != results[i])
8892                 {
8893                         test_result = false;
8894                         break;
8895                 }
8896         }
8897
8898         /* Anything from start_pos should be incremented by 1 */
8899         int diff = 0;
8900         for (size_t i = 0; i < n_entries; ++i)
8901         {
8902                 /* Tesselation evaluation can be called several times
8903                  In here, check the increment is consistent over all results.
8904                  */
8905                 if (tested_shader_type == TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE)
8906                 {
8907                         if (i == 0)
8908                         {
8909                                 diff = static_cast<int>(results[i + start_pos]) - static_cast<int>(i);
8910                                 if (diff <= 0)
8911                                 {
8912                                         test_result = false;
8913                                         break;
8914                                 }
8915                         }
8916                         else if ((static_cast<int>(results[i + start_pos]) - static_cast<int>(i)) != diff)
8917                         {
8918                                 test_result = false;
8919                                 break;
8920                         }
8921                 }
8922                 else
8923                 {
8924                         if (i + 1 != results[i + start_pos])
8925                         {
8926                                 test_result = false;
8927                                 break;
8928                         }
8929                 }
8930         }
8931
8932         gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
8933         GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
8934
8935         /* Deallocate any resources used. */
8936         gl.deleteBuffers(1, &buffer_object_id);
8937         this->delete_objects();
8938
8939         if (false == test_result)
8940         {
8941                 TCU_FAIL("Invalid results.");
8942         }
8943 }
8944
8945 /* Generates the shader source code for the SubroutineFunctionCalls1
8946  * array tests, attempts to build and execute test program
8947  *
8948  * @tparam API               Tested API descriptor
8949  *
8950  * @param tested_shader_type The type of shader that is being tested
8951  */
8952 template <class API>
8953 void SubroutineFunctionCalls1<API>::test_shader_compilation(
8954         typename TestCaseBase<API>::TestShaderType tested_shader_type)
8955 {
8956         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
8957                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
8958                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
8959                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
8960         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
8961
8962         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
8963                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
8964                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
8965                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
8966                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
8967         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
8968
8969         const std::string iteration_loop_end = "                }\n"
8970                                                                                    "            }\n"
8971                                                                                    "        }\n"
8972                                                                                    "    }\n";
8973         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
8974                                                                                          "    {\n"
8975                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
8976                                                                                          "        {\n"
8977                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
8978                                                                                          "            {\n"
8979                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
8980                                                                                          "                {\n";
8981         const glcts::test_var_type* var_types_set = var_types_set_es;
8982         size_t                                          num_var_types = num_var_types_es;
8983         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
8984
8985         if (API::USE_DOUBLE)
8986         {
8987                 var_types_set = var_types_set_gl;
8988                 num_var_types = num_var_types_gl;
8989         }
8990
8991         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
8992         {
8993                 _supported_variable_types_map_const_iterator var_iterator =
8994                         supported_variable_types_map.find(var_types_set[var_type_index]);
8995
8996                 if (var_iterator != supported_variable_types_map.end())
8997                 {
8998                         std::string iterator_declaration = "    " + var_iterator->second.iterator_type +
8999                                                                                            " iterator = " + var_iterator->second.iterator_initialization + ";\n";
9000
9001                         std::string function_definition;
9002                         std::string function_use;
9003                         std::string verification;
9004
9005                         function_definition += "// Subroutine types\n"
9006                                                                    "subroutine void out_routine_type(out ";
9007                         function_definition += var_iterator->second.type;
9008                         function_definition += " output_array[2][2][2][2]);\n\n"
9009                                                                    "// Subroutine definitions\n"
9010                                                                    "subroutine(out_routine_type) void original_routine(out ";
9011                         function_definition += var_iterator->second.type;
9012                         function_definition += " output_array[2][2][2][2]) {\n";
9013                         function_definition += iterator_declaration;
9014                         function_definition += iteration_loop_start;
9015                         function_definition += "                                   output_array[a][b][c][d] = " +
9016                                                                    var_iterator->second.variable_type_initializer1 + ";\n";
9017                         function_definition +=
9018                                 "                                   iterator += " + var_iterator->second.iterator_type + "(1);\n";
9019                         function_definition += iteration_loop_end;
9020                         function_definition += "}\n\n";
9021                         function_definition += "subroutine(out_routine_type) void new_routine(out ";
9022                         function_definition += var_iterator->second.type;
9023                         function_definition += " output_array[2][2][2][2]) {\n";
9024                         function_definition += iterator_declaration;
9025                         function_definition += iteration_loop_start;
9026                         function_definition += "                                   output_array[a][b][c][d] = " +
9027                                                                    var_iterator->second.variable_type_initializer1 + ";\n";
9028                         function_definition +=
9029                                 "                                   iterator -= " + var_iterator->second.iterator_type + "(1);\n";
9030                         function_definition += iteration_loop_end;
9031                         function_definition += "}\n\n"
9032                                                                    "// Subroutine uniform\n"
9033                                                                    "subroutine uniform out_routine_type routine;\n";
9034
9035                         function_use = "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
9036                         function_use += "    routine(my_array);";
9037
9038                         verification = iterator_declaration;
9039                         verification += "    float result = 1.0;\n";
9040                         verification += iteration_loop_start;
9041                         verification += "                                   if (my_array[a][b][c][d] " +
9042                                                         var_iterator->second.specific_element +
9043                                                         " != iterator)\n"
9044                                                         "                                   {\n"
9045                                                         "                                       result = 0.0;\n"
9046                                                         "                                   }\n"
9047                                                         "                                   iterator += " +
9048                                                         var_iterator->second.iterator_type + "(1);\n";
9049                         verification += iteration_loop_end;
9050
9051                         if (false == test_compute)
9052                         {
9053                                 execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, true);
9054                                 execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, false);
9055                         }
9056                         else
9057                         {
9058                                 execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, true);
9059                                 execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, false);
9060                         }
9061
9062                         /* Deallocate any resources used. */
9063                         this->delete_objects();
9064                 } /* if var_type iterator found */
9065                 else
9066                 {
9067                         TCU_FAIL("Type not found.");
9068                 }
9069         } /* for (int var_type_index = 0; ...) */
9070 }
9071
9072 /** Executes test for compute program
9073  *
9074  * @tparam API                  Tested API descriptor
9075  *
9076  * @param tested_shader_type    The type of shader that is being tested
9077  * @param function_definition   Definition used to prepare shader
9078  * @param function_use          Use of definition
9079  * @param verification          Result verification
9080  * @param use_original          Selects if "original_routine" - true or "new_routine" is choosen
9081  * @param expect_invalid_result Does test expects invalid results
9082  **/
9083 template <class API>
9084 void SubroutineFunctionCalls1<API>::execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
9085                                                                                                                   const std::string& function_definition,
9086                                                                                                                   const std::string& function_use,
9087                                                                                                                   const std::string& verification, bool use_original,
9088                                                                                                                   bool expect_invalid_result)
9089 {
9090         const std::string& compute_shader_source =
9091                 prepare_compute_shader(tested_shader_type, function_definition, function_use, verification);
9092         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
9093
9094         this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string,
9095                                                                 compute_shader_source, false, false);
9096
9097         /* We are now ready to verify whether the returned size is correct. */
9098         unsigned char     buffer[4]                      = { 0 };
9099         glw::GLuint                framebuffer_object_id = 0;
9100         glw::GLint                 location                              = -1;
9101         glw::GLuint                routine_index                 = -1;
9102         glw::GLuint                routine_location              = -1;
9103         const glw::GLchar* routine_name                  = "original_routine";
9104         const glw::GLenum  shader_type                   = GL_COMPUTE_SHADER;
9105         glw::GLuint                texture_object_id     = 0;
9106
9107         if (false == use_original)
9108         {
9109                 routine_name = "new_routine";
9110         }
9111
9112         gl.useProgram(this->program_object_id);
9113         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
9114
9115         /* Select subroutine */
9116         routine_index = gl.getSubroutineIndex(this->program_object_id, shader_type, routine_name);
9117         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() failed.");
9118
9119         routine_location = gl.getSubroutineUniformLocation(this->program_object_id, shader_type, "routine");
9120         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() failed.");
9121
9122         if (0 != routine_location)
9123         {
9124                 TCU_FAIL("Subroutine location is invalid");
9125         }
9126
9127         gl.uniformSubroutinesuiv(shader_type, 1, &routine_index);
9128         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() failed.");
9129
9130         /* Prepare texture */
9131         gl.genTextures(1, &texture_object_id);
9132         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
9133
9134         gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
9135         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
9136
9137         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
9138         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
9139
9140         gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
9141                                                 GL_WRITE_ONLY, GL_RGBA8);
9142         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed.");
9143
9144         location = gl.getUniformLocation(this->program_object_id, "uni_image");
9145         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
9146
9147         if (-1 == location)
9148         {
9149                 TCU_FAIL("Uniform is inactive");
9150         }
9151
9152         gl.uniform1i(location, 0 /* image unit */);
9153         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
9154
9155         /* Execute */
9156         gl.dispatchCompute(1, 1, 1);
9157         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9158
9159         /* Verify */
9160         gl.genFramebuffers(1, &framebuffer_object_id);
9161         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
9162
9163         gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
9164         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
9165
9166         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
9167         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
9168
9169         gl.viewport(0, 0, 1, 1);
9170         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
9171
9172         gl.readBuffer(GL_COLOR_ATTACHMENT0);
9173         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
9174
9175         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
9176         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
9177
9178         if ((buffer[0] != 255) != expect_invalid_result)
9179         {
9180                 TCU_FAIL("Invalid result was returned.");
9181         }
9182
9183         /* Delete generated objects. */
9184         gl.deleteTextures(1, &texture_object_id);
9185         gl.deleteFramebuffers(1, &framebuffer_object_id);
9186         GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
9187 }
9188
9189 /** Executes test for draw program
9190  *
9191  * @tparam API                  Tested API descriptor
9192  *
9193  * @param tested_shader_type    The type of shader that is being tested
9194  * @param function_definition   Definition used to prepare shader
9195  * @param function_use          Use of definition
9196  * @param verification          Result verification
9197  * @param use_original          Selects if "original_routine" - true or "new_routine" is choosen
9198  * @param expect_invalid_result Does test expects invalid results
9199  **/
9200 template <class API>
9201 void SubroutineFunctionCalls1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
9202                                                                                                           const std::string&                                             function_definition,
9203                                                                                                           const std::string& function_use, const std::string& verification,
9204                                                                                                           bool use_original, bool expect_invalid_result)
9205 {
9206         const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
9207
9208         if (API::USE_ALL_SHADER_STAGES)
9209         {
9210                 const std::string& compute_shader_source = empty_string;
9211                 const std::string& fragment_shader_source =
9212                         this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
9213                 const std::string& geometry_shader_source =
9214                         this->prepare_geometry_shader(tested_shader_type, function_definition, function_use, verification);
9215                 const std::string& tess_ctrl_shader_source =
9216                         this->prepare_tess_ctrl_shader(tested_shader_type, function_definition, function_use, verification);
9217                 const std::string& tess_eval_shader_source =
9218                         this->prepare_tess_eval_shader(tested_shader_type, function_definition, function_use, verification);
9219                 const std::string& vertex_shader_source =
9220                         this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
9221
9222                 switch (tested_shader_type)
9223                 {
9224                 case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
9225                 case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9226                         this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
9227                         break;
9228
9229                 case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9230                 case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9231                 case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
9232                 case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9233                         this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
9234                                                                                 geometry_shader_source, fragment_shader_source, compute_shader_source, false,
9235                                                                                 false);
9236                         break;
9237
9238                 default:
9239                         TCU_FAIL("Invalid enum");
9240                         break;
9241                 }
9242         }
9243         else
9244         {
9245                 const std::string& fragment_shader_source =
9246                         this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
9247                 const std::string& vertex_shader_source =
9248                         this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
9249
9250                 this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
9251         }
9252
9253         /* We are now ready to verify whether the returned size is correct. */
9254         unsigned char     buffer[4]                      = { 0 };
9255         glw::GLuint                framebuffer_object_id = 0;
9256         glw::GLuint                routine_index                 = -1;
9257         glw::GLuint                routine_location              = -1;
9258         const glw::GLchar* routine_name                  = "original_routine";
9259         glw::GLenum                shader_type                   = 0;
9260         glw::GLuint                texture_object_id     = 0;
9261         glw::GLuint                vao_id                                = 0;
9262
9263         switch (tested_shader_type)
9264         {
9265         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9266                 shader_type = GL_FRAGMENT_SHADER;
9267                 break;
9268         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9269                 shader_type = GL_VERTEX_SHADER;
9270                 break;
9271         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9272                 shader_type = GL_COMPUTE_SHADER;
9273                 break;
9274         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9275                 shader_type = GL_GEOMETRY_SHADER;
9276                 break;
9277         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9278                 shader_type = GL_TESS_CONTROL_SHADER;
9279                 break;
9280         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9281                 shader_type = GL_TESS_EVALUATION_SHADER;
9282                 break;
9283         default:
9284                 TCU_FAIL("Invalid shader type");
9285                 break;
9286         }
9287
9288         if (false == use_original)
9289         {
9290                 routine_name = "new_routine";
9291         }
9292
9293         gl.useProgram(this->program_object_id);
9294         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
9295
9296         /* Select subroutine */
9297         routine_index = gl.getSubroutineIndex(this->program_object_id, shader_type, routine_name);
9298         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() failed.");
9299
9300         routine_location = gl.getSubroutineUniformLocation(this->program_object_id, shader_type, "routine");
9301         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() failed.");
9302
9303         if (0 != routine_location)
9304         {
9305                 TCU_FAIL("Subroutine location is invalid");
9306         }
9307
9308         gl.uniformSubroutinesuiv(shader_type, 1, &routine_index);
9309         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() failed.");
9310
9311         /* Prepre texture */
9312         assert(0 == texture_object_id);
9313         gl.genTextures(1, &texture_object_id);
9314         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
9315
9316         gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
9317         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
9318
9319         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
9320         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
9321
9322         /* Prepare framebuffer */
9323         assert(0 == framebuffer_object_id);
9324         gl.genFramebuffers(1, &framebuffer_object_id);
9325         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
9326
9327         gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
9328         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
9329
9330         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
9331         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
9332
9333         gl.viewport(0, 0, 1, 1);
9334         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
9335
9336         /* Set VAO */
9337         assert(0 == vao_id);
9338         gl.genVertexArrays(1, &vao_id);
9339         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
9340
9341         gl.bindVertexArray(vao_id);
9342         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
9343
9344         switch (tested_shader_type)
9345         {
9346         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
9347         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9348                 gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
9349                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9350                 break;
9351
9352         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
9353         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9354                 /* Tesselation patch set up */
9355                 gl.patchParameteri(GL_PATCH_VERTICES, 1);
9356                 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
9357
9358                 gl.drawArrays(GL_PATCHES, 0, 1);
9359                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9360                 break;
9361
9362         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9363                 gl.drawArrays(GL_POINTS, 0, 1);
9364                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9365                 break;
9366
9367         default:
9368                 TCU_FAIL("Invalid enum");
9369                 break;
9370         }
9371
9372         /* Verify */
9373         gl.readBuffer(GL_COLOR_ATTACHMENT0);
9374         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
9375
9376         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
9377         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
9378
9379         const bool result = ((buffer[0] != 255) == expect_invalid_result);
9380
9381         /* Delete generated objects. */
9382         gl.useProgram(0);
9383         gl.bindTexture(GL_TEXTURE_2D, 0);
9384         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
9385         gl.bindVertexArray(0);
9386
9387         gl.deleteProgram(this->program_object_id);
9388         this->program_object_id = 0;
9389
9390         gl.deleteTextures(1, &texture_object_id);
9391         texture_object_id = 0;
9392
9393         gl.deleteFramebuffers(1, &framebuffer_object_id);
9394         framebuffer_object_id = 0;
9395
9396         gl.deleteVertexArrays(1, &vao_id);
9397         vao_id = 0;
9398
9399         GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
9400
9401         if (!result)
9402         {
9403                 TCU_FAIL("Invalid result was returned.");
9404         }
9405 }
9406
9407 /** Prepare shader
9408  *
9409  * @tparam API               Tested API descriptor
9410  *
9411  * @param tested_shader_type    The type of shader that is being tested
9412  * @param function_definition   Definition used to prepare shader
9413  * @param function_use          Use of definition
9414  * @param verification          Result verification
9415  **/
9416 template <class API>
9417 std::string SubroutineFunctionCalls1<API>::prepare_compute_shader(
9418         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9419         const std::string& function_use, const std::string& verification)
9420 {
9421         std::string compute_shader_source;
9422
9423         if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
9424         {
9425                 compute_shader_source = "writeonly uniform image2D uni_image;\n"
9426                                                                 "\n";
9427
9428                 /* User-defined function definition. */
9429                 compute_shader_source += function_definition;
9430                 compute_shader_source += "\n\n";
9431
9432                 /* Main function definition. */
9433                 compute_shader_source += shader_start;
9434                 compute_shader_source += function_use;
9435                 compute_shader_source += "\n\n";
9436                 compute_shader_source += verification;
9437                 compute_shader_source += "\n\n";
9438                 compute_shader_source += "\n"
9439                                                                  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
9440                                                                  "}\n"
9441                                                                  "\n";
9442         }
9443
9444         return compute_shader_source;
9445 }
9446
9447 /** Prepare shader
9448  *
9449  * @tparam API               Tested API descriptor
9450  *
9451  * @param tested_shader_type    The type of shader that is being tested
9452  * @param function_definition   Definition used to prepare shader
9453  * @param function_use          Use of definition
9454  * @param verification          Result verification
9455  **/
9456 template <class API>
9457 std::string SubroutineFunctionCalls1<API>::prepare_fragment_shader(
9458         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9459         const std::string& function_use, const std::string& verification)
9460 {
9461         std::string fragment_shader_source;
9462
9463         switch (tested_shader_type)
9464         {
9465         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9466                 break;
9467
9468         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9469                 fragment_shader_source = "out vec4 colour;\n\n";
9470
9471                 /* User-defined function definition. */
9472                 fragment_shader_source += function_definition;
9473                 fragment_shader_source += "\n\n";
9474
9475                 /* Main function definition. */
9476                 fragment_shader_source += shader_start;
9477                 fragment_shader_source += function_use;
9478                 fragment_shader_source += "\n\n";
9479                 fragment_shader_source += verification;
9480                 fragment_shader_source += "\n\n";
9481                 fragment_shader_source += "    colour = vec4(result);\n";
9482                 fragment_shader_source += shader_end;
9483                 break;
9484
9485         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9486         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9487         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: /* Fall through */
9488         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9489                 fragment_shader_source = "in float fs_result;\n\n"
9490                                                                  "out vec4 colour;\n\n"
9491                                                                  "void main()\n"
9492                                                                  "{\n"
9493                                                                  "    colour =  vec4(fs_result);\n"
9494                                                                  "}\n"
9495                                                                  "\n";
9496                 break;
9497
9498         default:
9499                 TCU_FAIL("Unrecognized shader object type.");
9500                 break;
9501         }
9502
9503         return fragment_shader_source;
9504 }
9505
9506 /** Prepare shader
9507  *
9508  * @tparam API               Tested API descriptor
9509  *
9510  * @param tested_shader_type    The type of shader that is being tested
9511  * @param function_definition   Definition used to prepare shader
9512  * @param function_use          Use of definition
9513  * @param verification          Result verification
9514  **/
9515 template <class API>
9516 std::string SubroutineFunctionCalls1<API>::prepare_geometry_shader(
9517         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9518         const std::string& function_use, const std::string& verification)
9519 {
9520         std::string geometry_shader_source;
9521
9522         switch (tested_shader_type)
9523         {
9524         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9525         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
9526         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9527                 break;
9528
9529         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
9530         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9531                 geometry_shader_source = "layout(points)                           in;\n"
9532                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
9533                                                                  "\n"
9534                                                                  "in  float tes_result[];\n"
9535                                                                  "out float fs_result;\n"
9536                                                                  "\n"
9537                                                                  "void main()\n"
9538                                                                  "{\n"
9539                                                                  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9540                                                                  "    fs_result    = tes_result[0];\n"
9541                                                                  "    EmitVertex();\n"
9542                                                                  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9543                                                                  "    fs_result    = tes_result[0];\n"
9544                                                                  "    EmitVertex();\n"
9545                                                                  "    gl_Position  = vec4(1, -1, 0, 1);\n"
9546                                                                  "    fs_result    = tes_result[0];\n"
9547                                                                  "    EmitVertex();\n"
9548                                                                  "    gl_Position  = vec4(1, 1, 0, 1);\n"
9549                                                                  "    fs_result    = tes_result[0];\n"
9550                                                                  "    EmitVertex();\n"
9551                                                                  "}\n";
9552                 break;
9553
9554         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9555                 geometry_shader_source = "layout(points)                           in;\n"
9556                                                                  "layout(triangle_strip, max_vertices = 4) out;\n"
9557                                                                  "\n"
9558                                                                  "out float fs_result;\n"
9559                                                                  "\n";
9560
9561                 /* User-defined function definition. */
9562                 geometry_shader_source += function_definition;
9563                 geometry_shader_source += "\n\n";
9564
9565                 /* Main function definition. */
9566                 geometry_shader_source += shader_start;
9567                 geometry_shader_source += function_use;
9568                 geometry_shader_source += "\n\n";
9569                 geometry_shader_source += verification;
9570                 geometry_shader_source += "\n\n";
9571                 geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
9572                                                                   "    fs_result    = result;\n"
9573                                                                   "    EmitVertex();\n"
9574                                                                   "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9575                                                                   "    fs_result    = result;\n"
9576                                                                   "    EmitVertex();\n"
9577                                                                   "    gl_Position  = vec4(1, -1, 0, 1);\n"
9578                                                                   "    fs_result    = result;\n"
9579                                                                   "    EmitVertex();\n"
9580                                                                   "    gl_Position  = vec4(1, 1, 0, 1);\n"
9581                                                                   "    fs_result    = result;\n"
9582                                                                   "    EmitVertex();\n"
9583                                                                   "}\n";
9584                 break;
9585
9586         default:
9587                 TCU_FAIL("Unrecognized shader object type.");
9588                 break;
9589         }
9590
9591         return geometry_shader_source;
9592 }
9593
9594 /** Prepare shader
9595  *
9596  * @tparam API               Tested API descriptor
9597  *
9598  * @param tested_shader_type    The type of shader that is being tested
9599  * @param function_definition   Definition used to prepare shader
9600  * @param function_use          Use of definition
9601  * @param verification          Result verification
9602  **/
9603 template <class API>
9604 std::string SubroutineFunctionCalls1<API>::prepare_tess_ctrl_shader(
9605         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9606         const std::string& function_use, const std::string& verification)
9607 {
9608         std::string tess_ctrl_shader_source;
9609
9610         switch (tested_shader_type)
9611         {
9612         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9613         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9614         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9615         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9616                 break;
9617
9618         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9619                 tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
9620                                                                   "\n"
9621                                                                   "out float tcs_result[];\n"
9622                                                                   "\n";
9623
9624                 /* User-defined function definition. */
9625                 tess_ctrl_shader_source += function_definition;
9626                 tess_ctrl_shader_source += "\n\n";
9627
9628                 /* Main function definition. */
9629                 tess_ctrl_shader_source += shader_start;
9630                 tess_ctrl_shader_source += function_use;
9631                 tess_ctrl_shader_source += "\n\n";
9632                 tess_ctrl_shader_source += verification;
9633                 tess_ctrl_shader_source += "\n\n";
9634                 tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
9635                                                                    "\n"
9636                                                                    "    gl_TessLevelOuter[0] = 1.0;\n"
9637                                                                    "    gl_TessLevelOuter[1] = 1.0;\n"
9638                                                                    "    gl_TessLevelOuter[2] = 1.0;\n"
9639                                                                    "    gl_TessLevelOuter[3] = 1.0;\n"
9640                                                                    "    gl_TessLevelInner[0] = 1.0;\n"
9641                                                                    "    gl_TessLevelInner[1] = 1.0;\n"
9642                                                                    "}\n";
9643                 break;
9644
9645         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9646                 tess_ctrl_shader_source = default_tc_shader_source;
9647                 break;
9648
9649         default:
9650                 TCU_FAIL("Unrecognized shader object type.");
9651                 break;
9652         }
9653
9654         return tess_ctrl_shader_source;
9655 }
9656
9657 /** Prepare shader
9658  *
9659  * @tparam API               Tested API descriptor
9660  *
9661  * @param tested_shader_type    The type of shader that is being tested
9662  * @param function_definition   Definition used to prepare shader
9663  * @param function_use          Use of definition
9664  * @param verification          Result verification
9665  **/
9666 template <class API>
9667 std::string SubroutineFunctionCalls1<API>::prepare_tess_eval_shader(
9668         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9669         const std::string& function_use, const std::string& verification)
9670 {
9671         std::string tess_eval_shader_source;
9672
9673         switch (tested_shader_type)
9674         {
9675         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9676         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9677         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9678         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9679                 break;
9680
9681         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9682                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
9683                                                                   "\n"
9684                                                                   "in  float tcs_result[];\n"
9685                                                                   "out float tes_result;\n"
9686                                                                   "\n"
9687                                                                   "void main()\n"
9688                                                                   "{\n"
9689                                                                   "    tes_result = tcs_result[0];\n"
9690                                                                   "}\n";
9691                 break;
9692
9693         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9694                 tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
9695                                                                   "\n"
9696                                                                   "out float tes_result;\n"
9697                                                                   "\n";
9698
9699                 /* User-defined function definition. */
9700                 tess_eval_shader_source += function_definition;
9701                 tess_eval_shader_source += "\n\n";
9702
9703                 /* Main function definition. */
9704                 tess_eval_shader_source += shader_start;
9705                 tess_eval_shader_source += function_use;
9706                 tess_eval_shader_source += "\n\n";
9707                 tess_eval_shader_source += verification;
9708                 tess_eval_shader_source += "\n\n";
9709                 tess_eval_shader_source += "    tes_result = result;\n"
9710                                                                    "}\n";
9711                 break;
9712
9713         default:
9714                 TCU_FAIL("Unrecognized shader object type.");
9715                 break;
9716         }
9717
9718         return tess_eval_shader_source;
9719 }
9720
9721 /** Prepare shader
9722  *
9723  * @tparam API               Tested API descriptor
9724  *
9725  * @param tested_shader_type    The type of shader that is being tested
9726  * @param function_definition   Definition used to prepare shader
9727  * @param function_use          Use of definition
9728  * @param verification          Result verification
9729  **/
9730 template <class API>
9731 std::string SubroutineFunctionCalls1<API>::prepare_vertex_shader(
9732         typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9733         const std::string& function_use, const std::string& verification)
9734 {
9735         std::string vertex_shader_source;
9736
9737         switch (tested_shader_type)
9738         {
9739         case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9740                 break;
9741
9742         case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9743                 vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
9744                                                            "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
9745                                                            "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
9746                                                            "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
9747                                                            "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
9748                                                            "\n"
9749                                                            "void main()\n"
9750                                                            "{\n"
9751                                                            "    gl_Position = vertex_positions[gl_VertexID];"
9752                                                            "}\n\n";
9753                 break;
9754
9755         case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9756         case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9757         case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9758                 vertex_shader_source = default_vertex_shader_source;
9759                 break;
9760
9761         case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9762                 /* Vertex shader source. */
9763                 vertex_shader_source = "out float fs_result;\n\n";
9764                 vertex_shader_source += "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
9765                                                                 "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
9766                                                                 "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
9767                                                                 "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
9768                                                                 "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n\n";
9769
9770                 /* User-defined function definition. */
9771                 vertex_shader_source += function_definition;
9772                 vertex_shader_source += "\n\n";
9773
9774                 /* Main function definition. */
9775                 vertex_shader_source += shader_start;
9776                 vertex_shader_source += function_use;
9777                 vertex_shader_source += "\n\n";
9778                 vertex_shader_source += verification;
9779                 vertex_shader_source += "\n\n";
9780                 vertex_shader_source += "    fs_result   = result;\n"
9781                                                                 "    gl_Position = vertex_positions[gl_VertexID];\n";
9782                 vertex_shader_source += shader_end;
9783                 break;
9784
9785         default:
9786                 TCU_FAIL("Unrecognized shader object type.");
9787                 break;
9788         }
9789
9790         return vertex_shader_source;
9791 }
9792
9793 /* Generates the shader source code for the InteractionFunctionCalls2
9794  * array tests, and attempts to build and execute test program.
9795  *
9796  * @tparam API               Tested API descriptor
9797  *
9798  * @param tested_shader_type The type of shader that is being tested
9799  */
9800 template <class API>
9801 void SubroutineFunctionCalls2<API>::test_shader_compilation(
9802         typename TestCaseBase<API>::TestShaderType tested_shader_type)
9803 {
9804         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9805                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9806                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9807                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
9808         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
9809
9810         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9811                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9812                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9813                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
9814                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
9815         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
9816
9817         const std::string iteration_loop_end = "                }\n"
9818                                                                                    "            }\n"
9819                                                                                    "        }\n"
9820                                                                                    "    }\n";
9821         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
9822                                                                                          "    {\n"
9823                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
9824                                                                                          "        {\n"
9825                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
9826                                                                                          "            {\n"
9827                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
9828                                                                                          "                {\n";
9829         const std::string multiplier_array = "const int[] multiplier_array = int[]( 1,  2,  3,  4,  5,  6,  7,  8,\n"
9830                                                                                  "                                     11, 12, 13, 14, 15, 16, 17, 18,\n"
9831                                                                                  "                                     21, 22, 23, 24, 25, 26, 27, 28,\n"
9832                                                                                  "                                     31, 32, 33, 34, 35, 36, 37, 38,\n"
9833                                                                                  "                                     41, 42, 43, 44, 45, 46, 47, 48,\n"
9834                                                                                  "                                     51, 52, 53, 54, 55, 56, 57, 58,\n"
9835                                                                                  "                                     61, 62, 63, 64, 65, 66, 67, 68,\n"
9836                                                                                  "                                     71, 72, 73, 74, 75, 76, 77, 78,\n"
9837                                                                                  "                                     81, 82, 83, 84, 85, 86, 87, 88);\n";
9838         const glcts::test_var_type* var_types_set = var_types_set_es;
9839         size_t                                          num_var_types = num_var_types_es;
9840         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
9841
9842         if (API::USE_DOUBLE)
9843         {
9844                 var_types_set = var_types_set_gl;
9845                 num_var_types = num_var_types_gl;
9846         }
9847
9848         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
9849         {
9850                 _supported_variable_types_map_const_iterator var_iterator =
9851                         supported_variable_types_map.find(var_types_set[var_type_index]);
9852
9853                 if (var_iterator != supported_variable_types_map.end())
9854                 {
9855                         std::string function_definition;
9856                         std::string function_use;
9857                         std::string verification;
9858
9859                         function_definition += multiplier_array;
9860
9861                         function_definition += "// Subroutine types\n"
9862                                                                    "subroutine void inout_routine_type(inout ";
9863                         function_definition += var_iterator->second.type;
9864                         function_definition += " inout_array[2][2][2][2]);\n\n"
9865                                                                    "// Subroutine definitions\n"
9866                                                                    "subroutine(inout_routine_type) void original_routine(inout ";
9867                         function_definition += var_iterator->second.type;
9868                         function_definition += " inout_array[2][2][2][2]) {\n"
9869                                                                    "    uint i = 0u;\n";
9870                         function_definition += iteration_loop_start;
9871                         function_definition += "                                   inout_array[a][b][c][d] *= " +
9872                                                                    var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n";
9873                         function_definition += "                                   i+= 1u;\n";
9874                         function_definition += iteration_loop_end;
9875                         function_definition += "}\n\n"
9876                                                                    "subroutine(inout_routine_type) void new_routine(inout ";
9877                         function_definition += var_iterator->second.type;
9878                         function_definition += " inout_array[2][2][2][2]) {\n"
9879                                                                    "    uint i = 0u;\n";
9880                         function_definition += iteration_loop_start;
9881                         function_definition += "                                   inout_array[a][b][c][d] /= " +
9882                                                                    var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n";
9883                         function_definition += "                                   i+= 1u;\n";
9884                         function_definition += iteration_loop_end;
9885                         function_definition += "}\n\n"
9886                                                                    "// Subroutine uniform\n"
9887                                                                    "subroutine uniform inout_routine_type routine;\n";
9888
9889                         function_use += "    float result = 1.0;\n";
9890                         function_use += "    uint iterator = 0u;\n";
9891                         function_use += "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
9892                         function_use += iteration_loop_start;
9893                         function_use += "                                   my_array[a][b][c][d] = " +
9894                                                         var_iterator->second.variable_type_initializer2 + ";\n";
9895                         function_use += iteration_loop_end;
9896                         function_use += "    routine(my_array);";
9897
9898                         verification += iteration_loop_start;
9899                         verification += "                                   if (my_array[a][b][c][d] " +
9900                                                         var_iterator->second.specific_element + "!= " + var_iterator->second.iterator_type +
9901                                                         "(multiplier_array[iterator % 64u]))\n"
9902                                                         "                                   {\n"
9903                                                         "                                       result = 0.0;\n"
9904                                                         "                                   }\n"
9905                                                         "                                   iterator += 1u;\n";
9906                         verification += iteration_loop_end;
9907
9908                         if (false == test_compute)
9909                         {
9910                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
9911                                                                                 true);
9912                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
9913                                                                                 false);
9914                         }
9915                         else
9916                         {
9917                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
9918                                                                                         true);
9919                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
9920                                                                                         false);
9921                         }
9922
9923                         /* Deallocate any resources used. */
9924                         this->delete_objects();
9925                 } /* if var_type iterator found */
9926                 else
9927                 {
9928                         TCU_FAIL("Type not found.");
9929                 }
9930         } /* for (int var_type_index = 0; ...) */
9931 }
9932
9933 /* Generates the shader source code for the SubroutineArgumentAliasing1
9934  * array tests, attempts to build and execute test program
9935  *
9936  * @tparam API               Tested API descriptor
9937  *
9938  * @param tested_shader_type The type of shader that is being tested
9939  */
9940 template <class API>
9941 void SubroutineArgumentAliasing1<API>::test_shader_compilation(
9942         typename TestCaseBase<API>::TestShaderType tested_shader_type)
9943 {
9944         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9945                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9946                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9947                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
9948         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
9949
9950         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9951                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9952                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9953                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
9954                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
9955         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
9956
9957         const std::string iteration_loop_end = "                }\n"
9958                                                                                    "            }\n"
9959                                                                                    "        }\n"
9960                                                                                    "    }\n";
9961         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
9962                                                                                          "    {\n"
9963                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
9964                                                                                          "        {\n"
9965                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
9966                                                                                          "            {\n"
9967                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
9968                                                                                          "                {\n";
9969         const glcts::test_var_type* var_types_set = var_types_set_es;
9970         size_t                                          num_var_types = num_var_types_es;
9971         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
9972
9973         if (API::USE_DOUBLE)
9974         {
9975                 var_types_set = var_types_set_gl;
9976                 num_var_types = num_var_types_gl;
9977         }
9978
9979         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
9980         {
9981                 _supported_variable_types_map_const_iterator var_iterator =
9982                         supported_variable_types_map.find(var_types_set[var_type_index]);
9983
9984                 if (var_iterator != supported_variable_types_map.end())
9985                 {
9986                         std::string function_definition;
9987                         std::string function_use;
9988                         std::string verification;
9989
9990                         function_definition += "// Subroutine types\n"
9991                                                                    "subroutine bool in_routine_type(";
9992                         function_definition += var_iterator->second.type;
9993                         function_definition += " x[2][2][2][2], ";
9994                         function_definition += var_iterator->second.type;
9995                         function_definition += " y[2][2][2][2]);\n\n"
9996                                                                    "// Subroutine definitions\n"
9997                                                                    "subroutine(in_routine_type) bool original_routine(";
9998                         function_definition += var_iterator->second.type;
9999                         function_definition += " x[2][2][2][2], ";
10000                         function_definition += var_iterator->second.type;
10001                         function_definition += " y[2][2][2][2])\n{\n";
10002                         function_definition += iteration_loop_start;
10003                         function_definition +=
10004                                 "                                   x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10005                         function_definition += iteration_loop_end;
10006                         function_definition += "\n";
10007                         function_definition += iteration_loop_start;
10008                         function_definition += "                                   if(y[a][b][c][d]";
10009                         if (var_iterator->second.type == "mat4") // mat4 comparison
10010                         {
10011                                 function_definition += "[0][0]";
10012                                 function_definition += " != float";
10013                         }
10014                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10015                         {
10016                                 function_definition += "[0][0]";
10017                                 function_definition += " != double";
10018                         }
10019                         else
10020                         {
10021                                 function_definition += " != ";
10022                                 function_definition += var_iterator->second.type;
10023                         }
10024                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10025                         function_definition += iteration_loop_end;
10026                         function_definition += "\n    return true;\n";
10027                         function_definition += "}\n\n"
10028                                                                    "subroutine(in_routine_type) bool new_routine(";
10029                         function_definition += var_iterator->second.type;
10030                         function_definition += " x[2][2][2][2], ";
10031                         function_definition += var_iterator->second.type;
10032                         function_definition += " y[2][2][2][2])\n{\n";
10033                         function_definition += iteration_loop_start;
10034                         function_definition +=
10035                                 "                                   y[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10036                         function_definition += iteration_loop_end;
10037                         function_definition += "\n";
10038                         function_definition += iteration_loop_start;
10039                         function_definition += "                                   if(x[a][b][c][d]";
10040                         if (var_iterator->second.type == "mat4") // mat4 comparison
10041                         {
10042                                 function_definition += "[0][0]";
10043                                 function_definition += " != float";
10044                         }
10045                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10046                         {
10047                                 function_definition += "[0][0]";
10048                                 function_definition += " != double";
10049                         }
10050                         else
10051                         {
10052                                 function_definition += " != ";
10053                                 function_definition += var_iterator->second.type;
10054                         }
10055                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10056                         function_definition += iteration_loop_end;
10057                         function_definition += "\n    return true;\n";
10058                         function_definition += "}\n\n"
10059                                                                    "// Subroutine uniform\n"
10060                                                                    "subroutine uniform in_routine_type routine;\n";
10061
10062                         function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10063                         function_use += iteration_loop_start;
10064                         function_use += "                                   z[a][b][c][d] = ";
10065                         function_use += var_iterator->second.type;
10066                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10067                         function_use += iteration_loop_end;
10068
10069                         verification = "    float result = 0.0;\n"
10070                                                    "    if(routine(z, z) == true)\n"
10071                                                    "    {\n"
10072                                                    "        result = 1.0;\n"
10073                                                    "    }\n"
10074                                                    "    else\n"
10075                                                    "    {\n"
10076                                                    "        result = 0.5;\n"
10077                                                    "    }\n";
10078
10079                         if (false == test_compute)
10080                         {
10081                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10082                                                                                 false);
10083                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10084                                                                                 false);
10085                         }
10086                         else
10087                         {
10088                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10089                                                                                         false);
10090                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10091                                                                                         false);
10092                         }
10093
10094                         /* Deallocate any resources used. */
10095                         this->delete_objects();
10096                 } /* if var_type iterator found */
10097                 else
10098                 {
10099                         TCU_FAIL("Type not found.");
10100                 }
10101         } /* for (int var_type_index = 0; ...) */
10102 }
10103
10104 /* Generates the shader source code for the SubroutineArgumentAliasing1
10105  * array tests, attempts to build and execute test program
10106  *
10107  * @tparam API               Tested API descriptor
10108  *
10109  * @param tested_shader_type The type of shader that is being tested
10110  */
10111 template <class API>
10112 void SubroutineArgumentAliasing2<API>::test_shader_compilation(
10113         typename TestCaseBase<API>::TestShaderType tested_shader_type)
10114 {
10115         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10116                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10117                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10118                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
10119         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
10120
10121         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10122                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10123                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10124                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
10125                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
10126         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
10127
10128         const std::string iteration_loop_end = "                }\n"
10129                                                                                    "            }\n"
10130                                                                                    "        }\n"
10131                                                                                    "    }\n";
10132         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
10133                                                                                          "    {\n"
10134                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
10135                                                                                          "        {\n"
10136                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
10137                                                                                          "            {\n"
10138                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
10139                                                                                          "                {\n";
10140         const glcts::test_var_type* var_types_set = var_types_set_es;
10141         size_t                                          num_var_types = num_var_types_es;
10142         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
10143
10144         if (API::USE_DOUBLE)
10145         {
10146                 var_types_set = var_types_set_gl;
10147                 num_var_types = num_var_types_gl;
10148         }
10149
10150         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
10151         {
10152                 _supported_variable_types_map_const_iterator var_iterator =
10153                         supported_variable_types_map.find(var_types_set[var_type_index]);
10154
10155                 if (var_iterator != supported_variable_types_map.end())
10156                 {
10157                         std::string function_definition;
10158                         std::string function_use;
10159                         std::string verification;
10160
10161                         function_definition += "// Subroutine types\n"
10162                                                                    "subroutine bool inout_routine_type(inout ";
10163                         function_definition += var_iterator->second.type;
10164                         function_definition += " x[2][2][2][2], inout ";
10165                         function_definition += var_iterator->second.type;
10166                         function_definition += " y[2][2][2][2]);\n\n"
10167                                                                    "// Subroutine definitions\n"
10168                                                                    "subroutine(inout_routine_type) bool original_routine(inout ";
10169                         function_definition += var_iterator->second.type;
10170                         function_definition += " x[2][2][2][2], inout ";
10171                         function_definition += var_iterator->second.type;
10172                         function_definition += " y[2][2][2][2])\n{\n";
10173                         function_definition += iteration_loop_start;
10174                         function_definition +=
10175                                 "                                   x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10176                         function_definition += iteration_loop_end;
10177                         function_definition += "\n";
10178                         function_definition += iteration_loop_start;
10179                         function_definition += "                                   if(y[a][b][c][d]";
10180                         if (var_iterator->second.type == "mat4") // mat4 comparison
10181                         {
10182                                 function_definition += "[0][0]";
10183                                 function_definition += " != float";
10184                         }
10185                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10186                         {
10187                                 function_definition += "[0][0]";
10188                                 function_definition += " != double";
10189                         }
10190                         else
10191                         {
10192                                 function_definition += " != ";
10193                                 function_definition += var_iterator->second.type;
10194                         }
10195                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10196                         function_definition += iteration_loop_end;
10197                         function_definition += "\n    return true;\n";
10198                         function_definition += "}\n\n"
10199                                                                    "subroutine(inout_routine_type) bool new_routine(inout ";
10200                         function_definition += var_iterator->second.type;
10201                         function_definition += " x[2][2][2][2], inout ";
10202                         function_definition += var_iterator->second.type;
10203                         function_definition += " y[2][2][2][2])\n{\n";
10204                         function_definition += iteration_loop_start;
10205                         function_definition +=
10206                                 "                                   y[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10207                         function_definition += iteration_loop_end;
10208                         function_definition += "\n";
10209                         function_definition += iteration_loop_start;
10210                         function_definition += "                                   if(x[a][b][c][d]";
10211                         if (var_iterator->second.type == "mat4") // mat4 comparison
10212                         {
10213                                 function_definition += "[0][0]";
10214                                 function_definition += " != float";
10215                         }
10216                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10217                         {
10218                                 function_definition += "[0][0]";
10219                                 function_definition += " != double";
10220                         }
10221                         else
10222                         {
10223                                 function_definition += " != ";
10224                                 function_definition += var_iterator->second.type;
10225                         }
10226                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10227                         function_definition += iteration_loop_end;
10228                         function_definition += "\n    return true;\n";
10229                         function_definition += "}\n\n"
10230                                                                    "// Subroutine uniform\n"
10231                                                                    "subroutine uniform inout_routine_type routine;\n";
10232
10233                         function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10234                         function_use += iteration_loop_start;
10235                         function_use += "                                   z[a][b][c][d] = ";
10236                         function_use += var_iterator->second.type;
10237                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10238                         function_use += iteration_loop_end;
10239
10240                         verification = "    float result = 0.0;\n"
10241                                                    "    if(routine(z, z) == true)\n"
10242                                                    "    {\n"
10243                                                    "        result = 1.0;\n"
10244                                                    "    }\n"
10245                                                    "    else\n"
10246                                                    "    {\n"
10247                                                    "        result = 0.5;\n"
10248                                                    "    }\n";
10249
10250                         if (false == test_compute)
10251                         {
10252                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10253                                                                                 false);
10254                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10255                                                                                 false);
10256                         }
10257                         else
10258                         {
10259                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10260                                                                                         false);
10261                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10262                                                                                         false);
10263                         }
10264
10265                         /* Deallocate any resources used. */
10266                         this->delete_objects();
10267                 } /* if var_type iterator found */
10268                 else
10269                 {
10270                         TCU_FAIL("Type not found.");
10271                 }
10272         } /* for (int var_type_index = 0; ...) */
10273 }
10274
10275 /* Generates the shader source code for the SubroutineArgumentAliasing1
10276  * array tests, attempts to build and execute test program
10277  *
10278  * @tparam API               Tested API descriptor
10279  *
10280  * @param tested_shader_type The type of shader that is being tested
10281  */
10282 template <class API>
10283 void SubroutineArgumentAliasing3<API>::test_shader_compilation(
10284         typename TestCaseBase<API>::TestShaderType tested_shader_type)
10285 {
10286         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10287                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10288                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10289                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
10290         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
10291
10292         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10293                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10294                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10295                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
10296                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
10297         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
10298
10299         const std::string iteration_loop_end = "                }\n"
10300                                                                                    "            }\n"
10301                                                                                    "        }\n"
10302                                                                                    "    }\n";
10303         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
10304                                                                                          "    {\n"
10305                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
10306                                                                                          "        {\n"
10307                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
10308                                                                                          "            {\n"
10309                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
10310                                                                                          "                {\n";
10311         const glcts::test_var_type* var_types_set = var_types_set_es;
10312         size_t                                          num_var_types = num_var_types_es;
10313         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
10314
10315         if (API::USE_DOUBLE)
10316         {
10317                 var_types_set = var_types_set_gl;
10318                 num_var_types = num_var_types_gl;
10319         }
10320
10321         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
10322         {
10323                 _supported_variable_types_map_const_iterator var_iterator =
10324                         supported_variable_types_map.find(var_types_set[var_type_index]);
10325
10326                 if (var_iterator != supported_variable_types_map.end())
10327                 {
10328                         std::string function_definition;
10329                         std::string function_use;
10330                         std::string verification;
10331
10332                         function_definition += "// Subroutine types\n"
10333                                                                    "subroutine bool out_routine_type(out ";
10334                         function_definition += var_iterator->second.type;
10335                         function_definition += " x[2][2][2][2], ";
10336                         function_definition += var_iterator->second.type;
10337                         function_definition += " y[2][2][2][2]);\n\n"
10338                                                                    "// Subroutine definitions\n"
10339                                                                    "subroutine(out_routine_type) bool original_routine(out ";
10340                         function_definition += var_iterator->second.type;
10341                         function_definition += " x[2][2][2][2], ";
10342                         function_definition += var_iterator->second.type;
10343                         function_definition += " y[2][2][2][2])\n{\n";
10344                         function_definition += iteration_loop_start;
10345                         function_definition +=
10346                                 "                                   x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10347                         function_definition += iteration_loop_end;
10348                         function_definition += "\n";
10349                         function_definition += iteration_loop_start;
10350                         function_definition += "                                   if(y[a][b][c][d]";
10351                         if (var_iterator->second.type == "mat4") // mat4 comparison
10352                         {
10353                                 function_definition += "[0][0]";
10354                                 function_definition += " != float";
10355                         }
10356                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10357                         {
10358                                 function_definition += "[0][0]";
10359                                 function_definition += " != double";
10360                         }
10361                         else
10362                         {
10363                                 function_definition += " != ";
10364                                 function_definition += var_iterator->second.type;
10365                         }
10366                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10367                         function_definition += iteration_loop_end;
10368                         function_definition += "\n    return true;\n";
10369                         function_definition += "}\n\n"
10370                                                                    "subroutine(out_routine_type) bool new_routine(out ";
10371                         function_definition += var_iterator->second.type;
10372                         function_definition += " x[2][2][2][2], ";
10373                         function_definition += var_iterator->second.type;
10374                         function_definition += " y[2][2][2][2])\n{\n";
10375                         function_definition += iteration_loop_start;
10376                         function_definition +=
10377                                 "                                   x[a][b][c][d] = " + var_iterator->second.type + "(321);\n";
10378                         function_definition += iteration_loop_end;
10379                         function_definition += "\n";
10380                         function_definition += iteration_loop_start;
10381                         function_definition += "                                   if(y[a][b][c][d]";
10382                         if (var_iterator->second.type == "mat4") // mat4 comparison
10383                         {
10384                                 function_definition += "[0][0]";
10385                                 function_definition += " != float";
10386                         }
10387                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10388                         {
10389                                 function_definition += "[0][0]";
10390                                 function_definition += " != double";
10391                         }
10392                         else
10393                         {
10394                                 function_definition += " != ";
10395                                 function_definition += var_iterator->second.type;
10396                         }
10397                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10398                         function_definition += iteration_loop_end;
10399                         function_definition += "\n    return true;\n";
10400                         function_definition += "}\n\n"
10401                                                                    "// Subroutine uniform\n"
10402                                                                    "subroutine uniform out_routine_type routine;\n";
10403
10404                         function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10405                         function_use += iteration_loop_start;
10406                         function_use += "                                   z[a][b][c][d] = ";
10407                         function_use += var_iterator->second.type;
10408                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10409                         function_use += iteration_loop_end;
10410
10411                         verification = "    float result = 0.0;\n"
10412                                                    "    if(routine(z, z) == true)\n"
10413                                                    "    {\n"
10414                                                    "        result = 1.0;\n"
10415                                                    "    }\n"
10416                                                    "    else\n"
10417                                                    "    {\n"
10418                                                    "        result = 0.5;\n"
10419                                                    "    }\n";
10420
10421                         if (false == test_compute)
10422                         {
10423                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10424                                                                                 false);
10425                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10426                                                                                 false);
10427                         }
10428                         else
10429                         {
10430                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10431                                                                                         false);
10432                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10433                                                                                         false);
10434                         }
10435
10436                         /* Deallocate any resources used. */
10437                         this->delete_objects();
10438                 } /* if var_type iterator found */
10439                 else
10440                 {
10441                         TCU_FAIL("Type not found.");
10442                 }
10443         } /* for (int var_type_index = 0; ...) */
10444 }
10445
10446 /* Generates the shader source code for the SubroutineArgumentAliasing1
10447  * array tests, attempts to build and execute test program
10448  *
10449  * @tparam API               Tested API descriptor
10450  *
10451  * @param tested_shader_type The type of shader that is being tested
10452  */
10453 template <class API>
10454 void SubroutineArgumentAliasing4<API>::test_shader_compilation(
10455         typename TestCaseBase<API>::TestShaderType tested_shader_type)
10456 {
10457         static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10458                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10459                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10460                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
10461         static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
10462
10463         static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10464                                                                                                                          VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10465                                                                                                                          VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10466                                                                                                                          VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
10467                                                                                                                          VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
10468         static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
10469
10470         const std::string iteration_loop_end = "                }\n"
10471                                                                                    "            }\n"
10472                                                                                    "        }\n"
10473                                                                                    "    }\n";
10474         const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
10475                                                                                          "    {\n"
10476                                                                                          "        for (uint b = 0u; b < 2u; b++)\n"
10477                                                                                          "        {\n"
10478                                                                                          "            for (uint c = 0u; c < 2u; c++)\n"
10479                                                                                          "            {\n"
10480                                                                                          "                for (uint d = 0u; d < 2u; d++)\n"
10481                                                                                          "                {\n";
10482         const glcts::test_var_type* var_types_set = var_types_set_es;
10483         size_t                                          num_var_types = num_var_types_es;
10484         const bool                                      test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
10485
10486         if (API::USE_DOUBLE)
10487         {
10488                 var_types_set = var_types_set_gl;
10489                 num_var_types = num_var_types_gl;
10490         }
10491
10492         for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
10493         {
10494                 _supported_variable_types_map_const_iterator var_iterator =
10495                         supported_variable_types_map.find(var_types_set[var_type_index]);
10496
10497                 if (var_iterator != supported_variable_types_map.end())
10498                 {
10499                         std::string function_definition;
10500                         std::string function_use;
10501                         std::string verification;
10502
10503                         function_definition += "// Subroutine types\n"
10504                                                                    "subroutine bool out_routine_type(";
10505                         function_definition += var_iterator->second.type;
10506                         function_definition += " x[2][2][2][2], out ";
10507                         function_definition += var_iterator->second.type;
10508                         function_definition += " y[2][2][2][2]);\n\n"
10509                                                                    "// Subroutine definitions\n"
10510                                                                    "subroutine(out_routine_type) bool original_routine(";
10511                         function_definition += var_iterator->second.type;
10512                         function_definition += " x[2][2][2][2], out ";
10513                         function_definition += var_iterator->second.type;
10514                         function_definition += " y[2][2][2][2])\n{\n";
10515                         function_definition += iteration_loop_start;
10516                         function_definition +=
10517                                 "                                   y[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10518                         function_definition += iteration_loop_end;
10519                         function_definition += "\n";
10520                         function_definition += iteration_loop_start;
10521                         function_definition += "                                   if(x[a][b][c][d]";
10522                         if (var_iterator->second.type == "mat4") // mat4 comparison
10523                         {
10524                                 function_definition += "[0][0]";
10525                                 function_definition += " != float";
10526                         }
10527                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10528                         {
10529                                 function_definition += "[0][0]";
10530                                 function_definition += " != double";
10531                         }
10532                         else
10533                         {
10534                                 function_definition += " != ";
10535                                 function_definition += var_iterator->second.type;
10536                         }
10537                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10538                         function_definition += iteration_loop_end;
10539                         function_definition += "\n    return true;\n";
10540                         function_definition += "}\n\n"
10541                                                                    "subroutine(out_routine_type) bool new_routine(";
10542                         function_definition += var_iterator->second.type;
10543                         function_definition += " x[2][2][2][2], out ";
10544                         function_definition += var_iterator->second.type;
10545                         function_definition += " y[2][2][2][2])\n{\n";
10546                         function_definition += iteration_loop_start;
10547                         function_definition +=
10548                                 "                                   y[a][b][c][d] = " + var_iterator->second.type + "(321);\n";
10549                         function_definition += iteration_loop_end;
10550                         function_definition += "\n";
10551                         function_definition += iteration_loop_start;
10552                         function_definition += "                                   if(x[a][b][c][d]";
10553                         if (var_iterator->second.type == "mat4") // mat4 comparison
10554                         {
10555                                 function_definition += "[0][0]";
10556                                 function_definition += " != float";
10557                         }
10558                         else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10559                         {
10560                                 function_definition += "[0][0]";
10561                                 function_definition += " != double";
10562                         }
10563                         else
10564                         {
10565                                 function_definition += " != ";
10566                                 function_definition += var_iterator->second.type;
10567                         }
10568                         function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10569                         function_definition += iteration_loop_end;
10570                         function_definition += "\n    return true;\n";
10571                         function_definition += "}\n\n"
10572                                                                    "// Subroutine uniform\n"
10573                                                                    "subroutine uniform out_routine_type routine;\n";
10574
10575                         function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10576                         function_use += iteration_loop_start;
10577                         function_use += "                                   z[a][b][c][d] = ";
10578                         function_use += var_iterator->second.type;
10579                         function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10580                         function_use += iteration_loop_end;
10581
10582                         verification = "    float result = 0.0;\n"
10583                                                    "    if(routine(z, z) == true)\n"
10584                                                    "    {\n"
10585                                                    "        result = 1.0;\n"
10586                                                    "    }\n"
10587                                                    "    else\n"
10588                                                    "    {\n"
10589                                                    "        result = 0.5;\n"
10590                                                    "    }\n";
10591
10592                         if (false == test_compute)
10593                         {
10594                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10595                                                                                 false);
10596                                 this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10597                                                                                 false);
10598                         }
10599                         else
10600                         {
10601                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10602                                                                                         false);
10603                                 this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10604                                                                                         false);
10605                         }
10606
10607                         /* Deallocate any resources used. */
10608                         this->delete_objects();
10609                 } /* if var_type iterator found */
10610                 else
10611                 {
10612                         TCU_FAIL("Type not found.");
10613                 }
10614         } /* for (int var_type_index = 0; ...) */
10615 }
10616
10617 /** Instantiates all tests and adds them as children to the node
10618  *
10619  * @tparam API    Tested API descriptor
10620  *
10621  * @param context CTS context
10622  **/
10623 template <class API>
10624 void initTests(TestCaseGroup& group, glcts::Context& context)
10625 {
10626         // Set up the map
10627         ArraysOfArrays::initializeMap<API>();
10628
10629         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsPrimitive<API>(context));
10630         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes1<API>(context));
10631         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes2<API>(context));
10632         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes3<API>(context));
10633         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes4<API>(context));
10634         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle1<API>(context));
10635         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle2<API>(context));
10636         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle3<API>(context));
10637         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle4<API>(context));
10638         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle5<API>(context));
10639         group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsFunctionParams<API>(context));
10640         group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes1<API>(context));
10641         group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes2<API>(context));
10642         group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes3<API>(context));
10643         group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes4<API>(context));
10644         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructors1<API>(context));
10645         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructors2<API>(context));
10646         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedConstructors<API>(context));
10647         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConst<API>(context));
10648
10649         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors1<API>(context));
10650         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors2<API>(context));
10651         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors3<API>(context));
10652         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors4<API>(context));
10653         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructorSizing1<API>(context));
10654         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructorSizing2<API>(context));
10655         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclStructConstructors<API>(context));
10656         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays1<API>(context));
10657         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays2<API>(context));
10658         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays3<API>(context));
10659         group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays4<API>(context));
10660         group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment1<API>(context));
10661         group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment2<API>(context));
10662         group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment3<API>(context));
10663         group.addChild(new glcts::ArraysOfArrays::ExpressionsTypeRestrictions1<API>(context));
10664         group.addChild(new glcts::ArraysOfArrays::ExpressionsTypeRestrictions2<API>(context));
10665         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar1<API>(context));
10666         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar2<API>(context));
10667         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar3<API>(context));
10668         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar4<API>(context));
10669         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray1<API>(context));
10670         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray2<API>(context));
10671         group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray3<API>(context));
10672         group.addChild(new glcts::ArraysOfArrays::ExpressionsDynamicIndexing1<API>(context));
10673         group.addChild(new glcts::ArraysOfArrays::ExpressionsDynamicIndexing2<API>(context));
10674         group.addChild(new glcts::ArraysOfArrays::ExpressionsEquality1<API>(context));
10675         group.addChild(new glcts::ArraysOfArrays::ExpressionsEquality2<API>(context));
10676         group.addChild(new glcts::ArraysOfArrays::ExpressionsLength1<API>(context));
10677         group.addChild(new glcts::ArraysOfArrays::ExpressionsLength2<API>(context));
10678         group.addChild(new glcts::ArraysOfArrays::ExpressionsLength3<API>(context));
10679         group.addChild(new glcts::ArraysOfArrays::ExpressionsInvalid1<API>(context));
10680         group.addChild(new glcts::ArraysOfArrays::ExpressionsInvalid2<API>(context));
10681
10682         group.addChild(new glcts::ArraysOfArrays::InteractionFunctionCalls1<API>(context));
10683         group.addChild(new glcts::ArraysOfArrays::InteractionFunctionCalls2<API>(context));
10684         group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing1<API>(context));
10685         group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing2<API>(context));
10686         group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing3<API>(context));
10687         group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing4<API>(context));
10688         group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing5<API>(context));
10689         group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing6<API>(context));
10690
10691         group.addChild(new glcts::ArraysOfArrays::InteractionUniforms1<API>(context));
10692         group.addChild(new glcts::ArraysOfArrays::InteractionUniforms2<API>(context));
10693         group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers1<API>(context));
10694         group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers2<API>(context));
10695         group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers3<API>(context));
10696         group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays1<API>(context));
10697         group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays2<API>(context));
10698         group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays3<API>(context));
10699         group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays4<API>(context));
10700
10701         if (API::USE_STORAGE_BLOCK)
10702         {
10703                 group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers1<API>(context));
10704                 group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers2<API>(context));
10705                 group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers3<API>(context));
10706         }
10707
10708         if (API::USE_ATOMIC)
10709         {
10710                 group.addChild(new glcts::ArraysOfArrays::AtomicDeclarationTest<API>(context));
10711                 group.addChild(new glcts::ArraysOfArrays::AtomicUsageTest<API>(context));
10712         }
10713
10714         if (API::USE_SUBROUTINE)
10715         {
10716                 group.addChild(new glcts::ArraysOfArrays::SubroutineFunctionCalls1<API>(context));
10717                 group.addChild(new glcts::ArraysOfArrays::SubroutineFunctionCalls2<API>(context));
10718                 group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing1<API>(context));
10719                 group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing2<API>(context));
10720                 group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing3<API>(context));
10721                 group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing4<API>(context));
10722         }
10723 }
10724 } /* namespace ArraysOfArrays */
10725
10726 /** Constructor
10727  *
10728  * @param context CTS context
10729  **/
10730 ArrayOfArraysTestGroup::ArrayOfArraysTestGroup(Context& context)
10731         : TestCaseGroup(context, "arrays_of_arrays", "Groups all tests that verify 'arrays of arrays' functionality.")
10732 {
10733         /* Left blank on purpose */
10734 }
10735
10736 /* Instantiates all tests and adds them as children to the node */
10737 void ArrayOfArraysTestGroup::init(void)
10738 {
10739         ArraysOfArrays::initTests<ArraysOfArrays::Interface::ES>(*this, m_context);
10740 }
10741
10742 /** Constructor
10743  *
10744  * @param context CTS context
10745  **/
10746 ArrayOfArraysTestGroupGL::ArrayOfArraysTestGroupGL(Context& context)
10747         : TestCaseGroup(context, "arrays_of_arrays_gl", "Groups all tests that verify 'arrays of arrays' functionality.")
10748 {
10749         /* Left blank on purpose */
10750 }
10751
10752 /* Instantiates all tests and adds them as children to the node */
10753 void ArrayOfArraysTestGroupGL::init(void)
10754 {
10755         ArraysOfArrays::initTests<ArraysOfArrays::Interface::GL>(*this, m_context);
10756 }
10757 } /* namespace glcts */