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