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