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