1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "es31cArrayOfArraysTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluDefs.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 
31 #include <algorithm>
32 #include <cassert>
33 #include <cstdio>
34 #include <string>
35 using std::string;
36 
37 /* Selects if debug output is enabled */
38 #define IS_DEBUG 0
39 #define IS_DEBUG_DUMP_ALL_SHADERS 0
40 
41 /* Selects if workaround in ExpressionsInvalid2 test is enabled */
42 #define WRKARD_EXPRESSIONSINVALID2 0
43 
44 #if IS_DEBUG
45 #include "tcuTestLog.hpp"
46 #endif
47 
48 namespace glcts
49 {
50 namespace ArraysOfArrays
51 {
52 namespace Interface
53 {
54 /* Sets limits on number of dimensions. Value 8 comes from ogirinal "ES" implementation.
55  * Explanation was as follows:
56  *
57  *     "The current specifations allow up to 8 array dimensions."
58  */
59 const size_t ES::MAX_ARRAY_DIMENSIONS = 8;
60 const size_t GL::MAX_ARRAY_DIMENSIONS = 8;
61 
62 /* API specific shader parts */
63 const char* ES::shader_version_gpu5 =
64 	"#version 310 es\n#extension GL_EXT_gpu_shader5 : require\nprecision mediump float;\n\n";
65 const char* ES::shader_version = "#version 310 es\nprecision mediump float;\n\n";
66 
67 const char* GL::shader_version_gpu5 = "#version 430 core\n\n";
68 const char* GL::shader_version		= "#version 430 core\n\n";
69 } /* namespace Interface */
70 
71 /* Dummy fragment shader source code.
72  * Used when testing the vertex shader. */
73 const std::string default_fragment_shader_source = "//default fragment shader\n"
74 												   "out vec4 color;\n"
75 												   "void main()\n"
76 												   "{\n"
77 												   "    color = vec4(1.0);\n"
78 												   "}\n";
79 
80 /* Dummy vertex shader source code.
81  * Used when testing the fragment shader. */
82 const std::string default_vertex_shader_source = "//default vertex shader\n"
83 												 "\n"
84 												 "void main()\n"
85 												 "{\n"
86 												 "    gl_Position = vec4(0.0,0.0,0.0,1.0);\n"
87 												 "}\n";
88 
89 /* Dummy geometry shader source code.
90  * Used when testing the other shaders. */
91 const std::string default_geometry_shader_source = "//default geometry\n"
92 												   "\n"
93 												   "void main()\n"
94 												   "{\n"
95 												   "    gl_Position  = vec4(-1, -1, 0, 1);\n"
96 												   "    EmitVertex();\n"
97 												   "    gl_Position  = vec4(-1, 1, 0, 1);\n"
98 												   "    EmitVertex();\n"
99 												   "    gl_Position  = vec4(1, -1, 0, 1);\n"
100 												   "    EmitVertex();\n"
101 												   "    gl_Position  = vec4(1, 1, 0, 1);\n"
102 												   "    EmitVertex();\n"
103 												   "}\n";
104 
105 /* Dummy tesselation control shader source code.
106  * Used when testing the other shaders. */
107 const std::string default_tc_shader_source = "//default tcs\n"
108 											 "\n"
109 											 "void main()\n"
110 											 "{\n"
111 											 "    gl_TessLevelOuter[0] = 1.0;\n"
112 											 "    gl_TessLevelOuter[1] = 1.0;\n"
113 											 "    gl_TessLevelOuter[2] = 1.0;\n"
114 											 "    gl_TessLevelOuter[3] = 1.0;\n"
115 											 "    gl_TessLevelInner[0] = 1.0;\n"
116 											 "    gl_TessLevelInner[1] = 1.0;\n"
117 											 "}\n";
118 
119 /* Dummy tesselation evaluation shader source code.
120  * Used when testing the other shaders. */
121 const std::string default_te_shader_source = "//default tes\n"
122 											 "\n"
123 											 "void main()\n"
124 											 "{\n"
125 											 "}\n";
126 
127 /* Pass-through shaders source code. Used when testing other stage. */
128 const std::string pass_fragment_shader_source = "//pass fragment shader\n"
129 												"in float fs_result;\n"
130 												"out vec4 color;\n"
131 												"\n"
132 												"void main()\n"
133 												"{\n"
134 												"    color = vec4(fs_result);\n"
135 												"}\n";
136 
137 const std::string pass_geometry_shader_source = "//pass geometry\n"
138 												"in  float gs_result[];\n"
139 												"out float fs_result;\n"
140 												"\n"
141 												"void main()\n"
142 												"{\n"
143 												"    gl_Position  = vec4(-1, -1, 0, 1);\n"
144 												"    fs_result = gs_result[0];\n"
145 												"    EmitVertex();\n"
146 												"    gl_Position  = vec4(-1, 1, 0, 1);\n"
147 												"    fs_result = gs_result[0];\n"
148 												"    EmitVertex();\n"
149 												"    gl_Position  = vec4(1, -1, 0, 1);\n"
150 												"    fs_result = gs_result[0];\n"
151 												"    EmitVertex();\n"
152 												"    gl_Position  = vec4(1, 1, 0, 1);\n"
153 												"    fs_result = gs_result[0];\n"
154 												"    EmitVertex();\n"
155 												"}\n";
156 
157 const std::string pass_te_shader_source = "//pass tes\n"
158 										  "in  float tcs_result[];\n"
159 										  "out float fs_result;\n"
160 										  "\n"
161 										  "void main()\n"
162 										  "{\n"
163 										  "    fs_result = tcs_result[0];\n"
164 										  "}\n";
165 
166 /* Empty string */
167 static const std::string empty_string = "";
168 
169 /* Beginning of a shader source code. */
170 const std::string shader_start = "void main()\n"
171 								 "{\n";
172 
173 /* End of a shader source code. */
174 const std::string shader_end = "}\n";
175 
176 /* Emit full screen quad from GS */
177 const std::string emit_quad = "    gl_Position  = vec4(-1, -1, 0, 1);\n"
178 							  "    EmitVertex();\n"
179 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
180 							  "    EmitVertex();\n"
181 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
182 							  "    EmitVertex();\n"
183 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
184 							  "    EmitVertex();\n";
185 
186 /* Set tesselation levels */
187 const std::string set_tesseation = "    gl_TessLevelOuter[0] = 1.0;\n"
188 								   "    gl_TessLevelOuter[1] = 1.0;\n"
189 								   "    gl_TessLevelOuter[2] = 1.0;\n"
190 								   "    gl_TessLevelOuter[3] = 1.0;\n"
191 								   "    gl_TessLevelInner[0] = 1.0;\n"
192 								   "    gl_TessLevelInner[1] = 1.0;\n";
193 
194 /* Input and output data type modifiers. */
195 const std::string in_out_type_modifiers[] = { "in", "out", "uniform" };
196 
197 /* Types and appropriate initialisers, used throughout these tests */
198 const var_descriptor var_descriptors[] = {
199 	{ "bool", "", "true", "false", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
200 	{ "int", "", "1", "0", "0", "int", "", "iterator", "1", "N/A", "N/A" },
201 	{ "uint", "", "1u", "0u", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
202 	{ "float", "", "1.0", "0.0", "0.0", "float", "", "iterator", "1.0", "N/A", "N/A" },
203 	{ "vec2", "", "vec2(1.0)", "vec2(0.0)", "0.0", "float", "[0]", "vec2(iterator)", "vec2(1.0)", "N/A", "N/A" },
204 	{ "vec3", "", "vec3(1.0)", "vec3(0.0)", "0.0", "float", "[0]", "vec3(iterator)", "vec3(1.0)", "N/A", "N/A" },
205 	{ "vec4", "", "vec4(1.0)", "vec4(0.0)", "0.0", "float", "[0]", "vec4(iterator)", "vec4(1.0)", "N/A", "N/A" },
206 	{ "bvec2", "", "bvec2(1)", "bvec2(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
207 	{ "bvec3", "", "bvec3(1)", "bvec3(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
208 	{ "bvec4", "", "bvec4(1)", "bvec4(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
209 	{ "ivec2", "", "ivec2(1)", "ivec2(0)", "0", "int", "[0]", "ivec2(iterator)", "ivec2(1)", "N/A", "N/A" },
210 	{ "ivec3", "", "ivec3(1)", "ivec3(0)", "0", "int", "[0]", "ivec3(iterator)", "ivec3(1)", "N/A", "N/A" },
211 	{ "ivec4", "", "ivec4(1)", "ivec4(0)", "0", "int", "[0]", "ivec4(iterator)", "ivec4(1)", "N/A", "N/A" },
212 	{ "uvec2", "", "uvec2(1u)", "uvec2(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
213 	{ "uvec3", "", "uvec3(1u)", "uvec3(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
214 	{ "uvec4", "", "uvec4(1u)", "uvec4(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
215 	{ "mat2", "", "mat2(1.0)", "mat2(0.0)", "0.0", "float", "[0][0]", "mat2(iterator)", "mat2(1.0)", "N/A", "N/A" },
216 	{ "mat3", "", "mat3(1.0)", "mat3(0.0)", "0.0", "float", "[0][0]", "mat3(iterator)", "mat3(1.0)", "N/A", "N/A" },
217 	{ "mat4", "", "mat4(1.0)", "mat4(0.0)", "0.0", "float", "[0][0]", "mat4(iterator)", "mat4(1.0)", "N/A", "N/A" },
218 	{ "mat2x2", "", "mat2x2(1.0)", "mat2x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
219 	{ "mat2x3", "", "mat2x3(1.0)", "mat2x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
220 	{ "mat2x4", "", "mat2x4(1.0)", "mat2x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
221 	{ "mat3x2", "", "mat3x2(1.0)", "mat3x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
222 	{ "mat3x3", "", "mat3x3(1.0)", "mat3x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
223 	{ "mat3x4", "", "mat3x4(1.0)", "mat3x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
224 	{ "mat4x2", "", "mat4x2(1.0)", "mat4x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
225 	{ "mat4x3", "", "mat4x3(1.0)", "mat4x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
226 	{ "mat4x4", "", "mat4x4(1.0)", "mat4x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
227 	{ "imageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
228 	{ "iimageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
229 	{ "uimageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
230 	{ "samplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
231 	{ "isamplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
232 	{ "usamplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
233 	{ "sampler2D", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "vec4" },
234 	{ "sampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" },
235 	{ "samplerCube", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" },
236 	{
237 		"samplerCubeShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec4(0.0)", "float",
238 	},
239 	{ "sampler2DShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "float" },
240 	{ "sampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" },
241 	{ "sampler2DArrayShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec4(0.0)", "float" },
242 	{ "isampler2D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "ivec4" },
243 	{ "isampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" },
244 	{ "isamplerCube", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" },
245 	{ "isampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" },
246 	{ "usampler2D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "uvec4" },
247 	{ "usampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" },
248 	{ "usamplerCube", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" },
249 	{ "usampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" },
250 };
251 
252 const var_descriptor var_double_descriptors[] = {
253 	{ "double", "", "1.0", "0.0", "0.0", "double", "", "iterator", "1.0", "N/A", "N/A" },
254 	{ "dmat2", "", "dmat2(1.0)", "dmat2(0.0)", "0.0", "double", "[0][0]", "dmat2(iterator)", "dmat2(1.0)", "N/A",
255 	  "N/A" },
256 	{ "dmat3", "", "dmat3(1.0)", "dmat3(0.0)", "0.0", "double", "[0][0]", "dmat3(iterator)", "dmat3(1.0)", "N/A",
257 	  "N/A" },
258 	{ "dmat4", "", "dmat4(1.0)", "dmat4(0.0)", "0.0", "double", "[0][0]", "dmat4(iterator)", "dmat4(1.0)", "N/A",
259 	  "N/A" },
260 	{ "dmat2x2", "", "dmat2x2(1.0)", "dmat2x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
261 	{ "dmat2x3", "", "dmat2x3(1.0)", "dmat2x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
262 	{ "dmat2x4", "", "dmat2x4(1.0)", "dmat2x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
263 	{ "dmat3x2", "", "dmat3x2(1.0)", "dmat3x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
264 	{ "dmat3x3", "", "dmat3x3(1.0)", "dmat3x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
265 	{ "dmat3x4", "", "dmat3x4(1.0)", "dmat3x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
266 	{ "dmat4x2", "", "dmat4x2(1.0)", "dmat4x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
267 	{ "dmat4x3", "", "dmat4x3(1.0)", "dmat4x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
268 	{ "dmat4x4", "", "dmat4x4(1.0)", "dmat4x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" },
269 };
270 
271 _supported_variable_types_map supported_variable_types_map;
272 
273 /** List of all supported variable types for es. */
274 const test_var_type var_types_es[] = {
275 	VAR_TYPE_BOOL,   VAR_TYPE_INT,	VAR_TYPE_UINT,   VAR_TYPE_FLOAT,  VAR_TYPE_VEC2,   VAR_TYPE_VEC3,
276 	VAR_TYPE_VEC4,   VAR_TYPE_BVEC2,  VAR_TYPE_BVEC3,  VAR_TYPE_BVEC4,  VAR_TYPE_IVEC2,  VAR_TYPE_IVEC3,
277 	VAR_TYPE_IVEC4,  VAR_TYPE_UVEC2,  VAR_TYPE_UVEC3,  VAR_TYPE_UVEC4,  VAR_TYPE_MAT2,   VAR_TYPE_MAT3,
278 	VAR_TYPE_MAT4,   VAR_TYPE_MAT2X2, VAR_TYPE_MAT2X3, VAR_TYPE_MAT2X4, VAR_TYPE_MAT3X2, VAR_TYPE_MAT3X3,
279 	VAR_TYPE_MAT3X4, VAR_TYPE_MAT4X2, VAR_TYPE_MAT4X3, VAR_TYPE_MAT4X4,
280 };
281 
282 const test_var_type* Interface::ES::var_types   = var_types_es;
283 const size_t		 Interface::ES::n_var_types = sizeof(var_types_es) / sizeof(var_types_es[0]);
284 
285 /** List of all supported variable types for gl. */
286 static const glcts::test_var_type var_types_gl[] = {
287 	VAR_TYPE_BOOL,	VAR_TYPE_INT,		VAR_TYPE_UINT,	VAR_TYPE_FLOAT,   VAR_TYPE_VEC2,	VAR_TYPE_VEC3,
288 	VAR_TYPE_VEC4,	VAR_TYPE_BVEC2,   VAR_TYPE_BVEC3,   VAR_TYPE_BVEC4,   VAR_TYPE_IVEC2,   VAR_TYPE_IVEC3,
289 	VAR_TYPE_IVEC4,   VAR_TYPE_UVEC2,   VAR_TYPE_UVEC3,   VAR_TYPE_UVEC4,   VAR_TYPE_MAT2,	VAR_TYPE_MAT3,
290 	VAR_TYPE_MAT4,	VAR_TYPE_MAT2X2,  VAR_TYPE_MAT2X3,  VAR_TYPE_MAT2X4,  VAR_TYPE_MAT3X2,  VAR_TYPE_MAT3X3,
291 	VAR_TYPE_MAT3X4,  VAR_TYPE_MAT4X2,  VAR_TYPE_MAT4X3,  VAR_TYPE_MAT4X4,  VAR_TYPE_DOUBLE,  VAR_TYPE_DMAT2,
292 	VAR_TYPE_DMAT3,   VAR_TYPE_DMAT4,   VAR_TYPE_DMAT2X2, VAR_TYPE_DMAT2X3, VAR_TYPE_DMAT2X4, VAR_TYPE_DMAT3X2,
293 	VAR_TYPE_DMAT3X3, VAR_TYPE_DMAT3X4, VAR_TYPE_DMAT4X2, VAR_TYPE_DMAT4X3, VAR_TYPE_DMAT4X4,
294 };
295 
296 const test_var_type* Interface::GL::var_types   = var_types_gl;
297 const size_t		 Interface::GL::n_var_types = sizeof(var_types_gl) / sizeof(var_types_gl[0]);
298 
299 /** List of all supported opaque types. */
300 const glcts::test_var_type opaque_var_types[] = {
301 	//Floating Point Sampler Types (opaque)
302 	VAR_TYPE_SAMPLER2D, VAR_TYPE_SAMPLER3D, VAR_TYPE_SAMPLERCUBE, VAR_TYPE_SAMPLERCUBESHADOW, VAR_TYPE_SAMPLER2DSHADOW,
303 	VAR_TYPE_SAMPLER2DARRAY, VAR_TYPE_SAMPLER2DARRAYSHADOW,
304 	//Signed Integer Sampler Types (opaque)
305 	VAR_TYPE_ISAMPLER2D, VAR_TYPE_ISAMPLER3D, VAR_TYPE_ISAMPLERCUBE, VAR_TYPE_ISAMPLER2DARRAY,
306 	//Unsigned Integer Sampler Types (opaque)
307 	VAR_TYPE_USAMPLER2D, VAR_TYPE_USAMPLER3D, VAR_TYPE_USAMPLERCUBE, VAR_TYPE_USAMPLER2DARRAY,
308 };
309 
310 /** Sets up the type map that will be used to look up the type names, initialisation
311  *  values, etc., associated with each of the types used within the array tests
312  *
313  **/
314 template <class API>
initializeMap()315 void initializeMap()
316 {
317 	int temp_index = 0;
318 
319 	// Set up the map
320 	supported_variable_types_map[VAR_TYPE_BOOL]					= var_descriptors[temp_index++];
321 	supported_variable_types_map[VAR_TYPE_INT]					= var_descriptors[temp_index++];
322 	supported_variable_types_map[VAR_TYPE_UINT]					= var_descriptors[temp_index++];
323 	supported_variable_types_map[VAR_TYPE_FLOAT]				= var_descriptors[temp_index++];
324 	supported_variable_types_map[VAR_TYPE_VEC2]					= var_descriptors[temp_index++];
325 	supported_variable_types_map[VAR_TYPE_VEC3]					= var_descriptors[temp_index++];
326 	supported_variable_types_map[VAR_TYPE_VEC4]					= var_descriptors[temp_index++];
327 	supported_variable_types_map[VAR_TYPE_BVEC2]				= var_descriptors[temp_index++];
328 	supported_variable_types_map[VAR_TYPE_BVEC3]				= var_descriptors[temp_index++];
329 	supported_variable_types_map[VAR_TYPE_BVEC4]				= var_descriptors[temp_index++];
330 	supported_variable_types_map[VAR_TYPE_IVEC2]				= var_descriptors[temp_index++];
331 	supported_variable_types_map[VAR_TYPE_IVEC3]				= var_descriptors[temp_index++];
332 	supported_variable_types_map[VAR_TYPE_IVEC4]				= var_descriptors[temp_index++];
333 	supported_variable_types_map[VAR_TYPE_UVEC2]				= var_descriptors[temp_index++];
334 	supported_variable_types_map[VAR_TYPE_UVEC3]				= var_descriptors[temp_index++];
335 	supported_variable_types_map[VAR_TYPE_UVEC4]				= var_descriptors[temp_index++];
336 	supported_variable_types_map[VAR_TYPE_MAT2]					= var_descriptors[temp_index++];
337 	supported_variable_types_map[VAR_TYPE_MAT3]					= var_descriptors[temp_index++];
338 	supported_variable_types_map[VAR_TYPE_MAT4]					= var_descriptors[temp_index++];
339 	supported_variable_types_map[VAR_TYPE_MAT2X2]				= var_descriptors[temp_index++];
340 	supported_variable_types_map[VAR_TYPE_MAT2X3]				= var_descriptors[temp_index++];
341 	supported_variable_types_map[VAR_TYPE_MAT2X4]				= var_descriptors[temp_index++];
342 	supported_variable_types_map[VAR_TYPE_MAT3X2]				= var_descriptors[temp_index++];
343 	supported_variable_types_map[VAR_TYPE_MAT3X3]				= var_descriptors[temp_index++];
344 	supported_variable_types_map[VAR_TYPE_MAT3X4]				= var_descriptors[temp_index++];
345 	supported_variable_types_map[VAR_TYPE_MAT4X2]				= var_descriptors[temp_index++];
346 	supported_variable_types_map[VAR_TYPE_MAT4X3]				= var_descriptors[temp_index++];
347 	supported_variable_types_map[VAR_TYPE_MAT4X4]				= var_descriptors[temp_index++];
348 	supported_variable_types_map[VAR_TYPE_IMAGEBUFFER]			= var_descriptors[temp_index++];
349 	supported_variable_types_map[VAR_TYPE_IIMAGEBUFFER]			= var_descriptors[temp_index++];
350 	supported_variable_types_map[VAR_TYPE_UIMAGEBUFFER]			= var_descriptors[temp_index++];
351 	supported_variable_types_map[VAR_TYPE_SAMPLERBUFFER]		= var_descriptors[temp_index++];
352 	supported_variable_types_map[VAR_TYPE_ISAMPLERBUFFER]		= var_descriptors[temp_index++];
353 	supported_variable_types_map[VAR_TYPE_USAMPLERBUFFER]		= var_descriptors[temp_index++];
354 	supported_variable_types_map[VAR_TYPE_SAMPLER2D]			= var_descriptors[temp_index++];
355 	supported_variable_types_map[VAR_TYPE_SAMPLER3D]			= var_descriptors[temp_index++];
356 	supported_variable_types_map[VAR_TYPE_SAMPLERCUBE]			= var_descriptors[temp_index++];
357 	supported_variable_types_map[VAR_TYPE_SAMPLERCUBESHADOW]	= var_descriptors[temp_index++];
358 	supported_variable_types_map[VAR_TYPE_SAMPLER2DSHADOW]		= var_descriptors[temp_index++];
359 	supported_variable_types_map[VAR_TYPE_SAMPLER2DARRAY]		= var_descriptors[temp_index++];
360 	supported_variable_types_map[VAR_TYPE_SAMPLER2DARRAYSHADOW] = var_descriptors[temp_index++];
361 	supported_variable_types_map[VAR_TYPE_ISAMPLER2D]			= var_descriptors[temp_index++];
362 	supported_variable_types_map[VAR_TYPE_ISAMPLER3D]			= var_descriptors[temp_index++];
363 	supported_variable_types_map[VAR_TYPE_ISAMPLERCUBE]			= var_descriptors[temp_index++];
364 	supported_variable_types_map[VAR_TYPE_ISAMPLER2DARRAY]		= var_descriptors[temp_index++];
365 	supported_variable_types_map[VAR_TYPE_USAMPLER2D]			= var_descriptors[temp_index++];
366 	supported_variable_types_map[VAR_TYPE_USAMPLER3D]			= var_descriptors[temp_index++];
367 	supported_variable_types_map[VAR_TYPE_USAMPLERCUBE]			= var_descriptors[temp_index++];
368 	supported_variable_types_map[VAR_TYPE_USAMPLER2DARRAY]		= var_descriptors[temp_index++];
369 
370 	if (API::USE_DOUBLE)
371 	{
372 		temp_index = 0;
373 
374 		supported_variable_types_map[VAR_TYPE_DOUBLE]  = var_double_descriptors[temp_index++];
375 		supported_variable_types_map[VAR_TYPE_DMAT2]   = var_double_descriptors[temp_index++];
376 		supported_variable_types_map[VAR_TYPE_DMAT3]   = var_double_descriptors[temp_index++];
377 		supported_variable_types_map[VAR_TYPE_DMAT4]   = var_double_descriptors[temp_index++];
378 		supported_variable_types_map[VAR_TYPE_DMAT2X2] = var_double_descriptors[temp_index++];
379 		supported_variable_types_map[VAR_TYPE_DMAT2X3] = var_double_descriptors[temp_index++];
380 		supported_variable_types_map[VAR_TYPE_DMAT2X4] = var_double_descriptors[temp_index++];
381 		supported_variable_types_map[VAR_TYPE_DMAT3X2] = var_double_descriptors[temp_index++];
382 		supported_variable_types_map[VAR_TYPE_DMAT3X3] = var_double_descriptors[temp_index++];
383 		supported_variable_types_map[VAR_TYPE_DMAT3X4] = var_double_descriptors[temp_index++];
384 		supported_variable_types_map[VAR_TYPE_DMAT4X2] = var_double_descriptors[temp_index++];
385 		supported_variable_types_map[VAR_TYPE_DMAT4X3] = var_double_descriptors[temp_index++];
386 		supported_variable_types_map[VAR_TYPE_DMAT4X4] = var_double_descriptors[temp_index++];
387 	}
388 }
389 
390 /** Macro appends default ending of main function to source string
391  *
392  * @param SOURCE Tested shader source
393  **/
394 #define DEFAULT_MAIN_ENDING(TYPE, SOURCE)                           \
395 	{                                                               \
396 		/* Apply stage specific stuff */                            \
397 		switch (TYPE)                                               \
398 		{                                                           \
399 		case TestCaseBase<API>::VERTEX_SHADER_TYPE:                 \
400 			SOURCE += "\n	gl_Position = vec4(0.0);\n";            \
401 			break;                                                  \
402 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:               \
403 			break;                                                  \
404 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:                \
405 			break;                                                  \
406 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:               \
407 			SOURCE += emit_quad;                                    \
408 			break;                                                  \
409 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:    \
410 			SOURCE += set_tesseation;                               \
411 			break;                                                  \
412 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: \
413 			break;                                                  \
414 		default:                                                    \
415 			TCU_FAIL("Unrecognized shader type.");                  \
416 			break;                                                  \
417 		}                                                           \
418                                                                     \
419 		/* End main function */                                     \
420 		SOURCE += shader_end;                                       \
421 	}
422 
423 /** Macro executes positive test selected on USE_ALL_SHADER_STAGES
424  *
425  * @param TYPE	Tested shader stage
426  * @param SOURCE Tested shader source
427  * @param DELETE Selects if program should be deleted afterwards
428  **/
429 #define EXECUTE_POSITIVE_TEST(TYPE, SOURCE, DELETE, GPU5)                              \
430 	{                                                                                  \
431 		const std::string* cs  = &empty_string;                                        \
432 		const std::string* vs  = &default_vertex_shader_source;                        \
433 		const std::string* tcs = &default_tc_shader_source;                            \
434 		const std::string* tes = &default_te_shader_source;                            \
435 		const std::string* gs  = &default_geometry_shader_source;                      \
436 		const std::string* fs  = &default_fragment_shader_source;                      \
437                                                                                        \
438 		switch (TYPE)                                                                  \
439 		{                                                                              \
440 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:                                   \
441 			cs  = &SOURCE;                                                             \
442 			vs  = &empty_string;                                                       \
443 			tcs = &empty_string;                                                       \
444 			tes = &empty_string;                                                       \
445 			gs  = &empty_string;                                                       \
446 			fs  = &empty_string;                                                       \
447 			break;                                                                     \
448 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:                                  \
449 			fs = &SOURCE;                                                              \
450 			break;                                                                     \
451 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:                                  \
452 			gs = &SOURCE;                                                              \
453 			break;                                                                     \
454 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:                       \
455 			tcs = &SOURCE;                                                             \
456 			break;                                                                     \
457 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:                    \
458 			tes = &SOURCE;                                                             \
459 			break;                                                                     \
460 		case TestCaseBase<API>::VERTEX_SHADER_TYPE:                                    \
461 			vs = &SOURCE;                                                              \
462 			break;                                                                     \
463 		default:                                                                       \
464 			TCU_FAIL("Invalid enum");                                                  \
465 			break;                                                                     \
466 		};                                                                             \
467                                                                                        \
468 		if (API::USE_ALL_SHADER_STAGES)                                                \
469 		{                                                                              \
470 			this->execute_positive_test(*vs, *tcs, *tes, *gs, *fs, *cs, DELETE, GPU5); \
471 		}                                                                              \
472 		else                                                                           \
473 		{                                                                              \
474 			this->execute_positive_test(*vs, *fs, DELETE, GPU5);                       \
475 		}                                                                              \
476 	}
477 
478 /** Macro executes either positive or negative test
479  *
480  * @param S		Selects negative test when 0, positive test otherwise
481  * @param TYPE	Tested shader stage
482  * @param SOURCE Tested shader source
483  **/
484 #define EXECUTE_SHADER_TEST(S, TYPE, SOURCE)              \
485 	if (S)                                                \
486 	{                                                     \
487 		EXECUTE_POSITIVE_TEST(TYPE, SOURCE, true, false); \
488 	}                                                     \
489 	else                                                  \
490 	{                                                     \
491 		this->execute_negative_test(TYPE, SOURCE);        \
492 	}
493 
494 /** Test case constructor.
495  *
496  * @tparam API        Tested API descriptor
497  *
498  * @param context     EGL context ID.
499  * @param name        Name of a test case.
500  * @param description Test case description.
501  **/
502 template <class API>
TestCaseBase(Context & context,const char * name,const char * description)503 TestCaseBase<API>::TestCaseBase(Context& context, const char* name, const char* description)
504 	: tcu::TestCase(context.getTestContext(), name, description)
505 	, context_id(context)
506 	, program_object_id(0)
507 	, compute_shader_object_id(0)
508 	, fragment_shader_object_id(0)
509 	, geometry_shader_object_id(0)
510 	, tess_ctrl_shader_object_id(0)
511 	, tess_eval_shader_object_id(0)
512 	, vertex_shader_object_id(0)
513 {
514 	/* Left blank on purpose */
515 }
516 
517 /** Clears up the shaders and program that were created during the tests
518  *
519  * @tparam API Tested API descriptor
520  */
521 template <class API>
delete_objects(void)522 void TestCaseBase<API>::delete_objects(void)
523 {
524 	const glw::Functions& gl = context_id.getRenderContext().getFunctions();
525 
526 	/* Release all ES objects that may have been created by iterate() */
527 	if (program_object_id != 0)
528 	{
529 		gl.deleteProgram(program_object_id);
530 		program_object_id = 0;
531 	}
532 
533 	/* Use default program object to be sure the objects were released. */
534 	gl.useProgram(0);
535 }
536 
537 /** Releases all OpenGL ES objects that were created for test case purposes.
538  *
539  * @tparam API Tested API descriptor
540  */
541 template <class API>
deinit(void)542 void TestCaseBase<API>::deinit(void)
543 {
544 	this->delete_objects();
545 }
546 
547 /** Runs the actual test for each shader type.
548  *
549  * @tparam API               Tested API descriptor
550  *
551  *  @return QP_TEST_RESULT_FAIL - test has failed;
552  *          QP_TEST_RESULT_PASS - test has succeeded;
553  **/
554 template <class API>
iterate(void)555 tcu::TestNode::IterateResult TestCaseBase<API>::iterate(void)
556 {
557 	test_shader_compilation(TestCaseBase<API>::VERTEX_SHADER_TYPE);
558 	test_shader_compilation(TestCaseBase<API>::FRAGMENT_SHADER_TYPE);
559 
560 	if (API::USE_ALL_SHADER_STAGES)
561 	{
562 		test_shader_compilation(TestCaseBase<API>::COMPUTE_SHADER_TYPE);
563 		test_shader_compilation(TestCaseBase<API>::GEOMETRY_SHADER_TYPE);
564 		test_shader_compilation(TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE);
565 		test_shader_compilation(TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE);
566 	}
567 
568 	return STOP;
569 }
570 
571 /** Generates a shader object of the specified type,
572  *  attaches the specified shader source,
573  *  compiles it, and returns the compilation result.
574  *
575  * @tparam API               Tested API descriptor
576  *
577  * @param shader_source      The source for the shader object.
578  * @param tested_shader_type The type of shader being compiled (vertex or fragment).
579  *
580  * @return Compilation result (GL_TRUE if the shader compilation succeeded, GL_FALSE otherwise).
581  **/
582 template <class API>
compile_shader_and_get_compilation_result(const std::string & tested_snippet,TestShaderType tested_shader_type,bool require_gpu_shader5)583 glw::GLint TestCaseBase<API>::compile_shader_and_get_compilation_result(const std::string& tested_snippet,
584 																		TestShaderType	 tested_shader_type,
585 																		bool			   require_gpu_shader5)
586 {
587 	static const char* preamble_cs = "\n"
588 									 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
589 									 "\n";
590 
591 	static const char* preamble_gs = "\n"
592 									 "layout(points)                           in;\n"
593 									 "layout(triangle_strip, max_vertices = 4) out;\n"
594 									 "\n";
595 
596 	static const char* preamble_tcs = "\n"
597 									  "layout(vertices = 1) out;\n"
598 									  "\n";
599 
600 	static const char* preamble_tes = "\n"
601 									  "layout(isolines, point_mode) in;\n"
602 									  "\n";
603 
604 	glw::GLint			  compile_status   = GL_TRUE;
605 	const glw::Functions& gl			   = context_id.getRenderContext().getFunctions();
606 	glw::GLint			  shader_object_id = 0;
607 
608 	std::string shader_source;
609 
610 	if (true == tested_snippet.empty())
611 	{
612 		return compile_status;
613 	}
614 
615 	if (require_gpu_shader5)
616 	{
617 		// Add the version number here, rather than in each individual test
618 		shader_source = API::shader_version_gpu5;
619 	}
620 	else
621 	{
622 		// Add the version number here, rather than in each individual test
623 		shader_source = API::shader_version;
624 	}
625 
626 	/* Apply stage specific stuff */
627 	switch (tested_shader_type)
628 	{
629 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
630 		break;
631 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
632 		break;
633 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
634 		shader_source += preamble_cs;
635 		break;
636 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
637 		shader_source += preamble_gs;
638 		break;
639 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
640 		shader_source += preamble_tcs;
641 		break;
642 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
643 		shader_source += preamble_tes;
644 		break;
645 	default:
646 		TCU_FAIL("Unrecognized shader type.");
647 		break;
648 	}
649 
650 	shader_source += tested_snippet;
651 
652 	/* Prepare shader object */
653 	switch (tested_shader_type)
654 	{
655 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
656 	{
657 		shader_object_id = gl.createShader(GL_VERTEX_SHADER);
658 		assert(0 == vertex_shader_object_id);
659 		vertex_shader_object_id = shader_object_id;
660 
661 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a vertex shader.");
662 
663 		break;
664 	} /* case TestCaseBase<API>::VERTEX_SHADER_TYPE: */
665 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
666 	{
667 		shader_object_id = gl.createShader(GL_FRAGMENT_SHADER);
668 		assert(0 == fragment_shader_object_id);
669 		fragment_shader_object_id = shader_object_id;
670 
671 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a fragment shader.");
672 
673 		break;
674 	} /* case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: */
675 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
676 	{
677 		shader_object_id = gl.createShader(GL_COMPUTE_SHADER);
678 		assert(0 == compute_shader_object_id);
679 		compute_shader_object_id = shader_object_id;
680 
681 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a compute shader.");
682 
683 		break;
684 	} /* case TestCaseBase<API>::COMPUTE_SHADER_TYPE: */
685 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
686 	{
687 		shader_object_id = gl.createShader(GL_GEOMETRY_SHADER);
688 		assert(0 == geometry_shader_object_id);
689 		geometry_shader_object_id = shader_object_id;
690 
691 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a geometry shader.");
692 
693 		break;
694 	} /* case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: */
695 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
696 	{
697 		shader_object_id = gl.createShader(GL_TESS_CONTROL_SHADER);
698 		assert(0 == tess_ctrl_shader_object_id);
699 		tess_ctrl_shader_object_id = shader_object_id;
700 
701 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a tesselation control shader.");
702 
703 		break;
704 	} /* case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: */
705 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
706 	{
707 		shader_object_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
708 		assert(0 == tess_eval_shader_object_id);
709 		tess_eval_shader_object_id = shader_object_id;
710 
711 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a tesselation evaluation shader.");
712 
713 		break;
714 	} /* case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: */
715 	default:
716 	{
717 		TCU_FAIL("Unrecognized shader type.");
718 
719 		break;
720 	} /* default: */
721 	} /* switch (tested_shader_type) */
722 
723 	/* Assign source code to the objects */
724 	const char* code_ptr = shader_source.c_str();
725 
726 #if IS_DEBUG_DUMP_ALL_SHADERS
727 	context_id.getTestContext().getLog() << tcu::TestLog::Message << "Compiling: " << tcu::TestLog::EndMessage;
728 	context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(code_ptr);
729 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
730 
731 	gl.shaderSource(shader_object_id, 1 /* count */, &code_ptr, NULL);
732 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed");
733 
734 	/* Compile the shader */
735 	gl.compileShader(shader_object_id);
736 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed");
737 
738 	/* Get the compilation result. */
739 	gl.getShaderiv(shader_object_id, GL_COMPILE_STATUS, &compile_status);
740 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed");
741 
742 #if IS_DEBUG
743 	if (GL_TRUE != compile_status)
744 	{
745 		glw::GLint  length = 0;
746 		std::string message;
747 
748 		/* Error log length */
749 		gl.getShaderiv(shader_object_id, GL_INFO_LOG_LENGTH, &length);
750 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
751 
752 		/* Prepare storage */
753 		message.resize(length, 0);
754 
755 		/* Get error log */
756 		gl.getShaderInfoLog(shader_object_id, length, 0, &message[0]);
757 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
758 
759 		context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0]
760 											 << tcu::TestLog::EndMessage;
761 
762 #if IS_DEBUG_DUMP_ALL_SHADERS
763 #else  /* IS_DEBUG_DUMP_ALL_SHADERS */
764 		context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(code_ptr);
765 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
766 	}
767 #endif /* IS_DEBUG */
768 
769 	return compile_status;
770 }
771 
772 /** Runs the negative test.
773  *  The shader sources are considered as invalid,
774  *  and the compilation of a shader object with the specified
775  *  shader source is expected to fail.
776  *
777  * @tparam API               Tested API descriptor
778  *
779  * @param tested_shader_type The type of shader object (can be fragment or vertex).
780  * @param shader_source      The source for the shader object to be used for this test.
781  *
782  *  @return QP_TEST_RESULT_FAIL - test has failed;
783  *          QP_TEST_RESULT_PASS - test has succeeded;
784  **/
785 template <class API>
execute_negative_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & shader_source)786 tcu::TestNode::IterateResult TestCaseBase<API>::execute_negative_test(
787 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& shader_source)
788 {
789 	glw::GLint			  compile_status = GL_FALSE;
790 	const char*			  error_message  = 0;
791 	const glw::Functions& gl			 = context_id.getRenderContext().getFunctions();
792 	bool				  test_result	= true;
793 
794 	/* Try to generate and compile the shader object. */
795 	switch (tested_shader_type)
796 	{
797 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
798 		error_message =
799 			"The fragment shader was expected to fail to compile, but the compilation process was successful.";
800 		break;
801 
802 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
803 		error_message =
804 			"The vertex shader was expected to fail to compile, but the compilation process was successful.";
805 
806 		break;
807 
808 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
809 		error_message =
810 			"The compute shader was expected to fail to compile, but the compilation process was successful.";
811 		break;
812 
813 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
814 		error_message =
815 			"The geometry shader was expected to fail to compile, but the compilation process was successful.";
816 		break;
817 
818 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
819 		error_message = "The tesselation control shader was expected to fail to compile, but the compilation process "
820 						"was successful.";
821 		break;
822 
823 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
824 		error_message = "The tesselation evaluation shader was expected to fail to compile, but the compilation "
825 						"process was successful.";
826 		break;
827 
828 	default:
829 		TCU_FAIL("Unrecognized shader type.");
830 		test_result = false;
831 
832 		break;
833 	} /* switch (shader_type) */
834 
835 	compile_status = compile_shader_and_get_compilation_result(shader_source, tested_shader_type);
836 
837 	if (compile_status == GL_TRUE)
838 	{
839 		TCU_FAIL(error_message);
840 
841 		test_result = false;
842 	}
843 
844 	/* Deallocate any resources used. */
845 	this->delete_objects();
846 	if (0 != compute_shader_object_id)
847 	{
848 		gl.deleteShader(compute_shader_object_id);
849 		compute_shader_object_id = 0;
850 	}
851 	if (0 != fragment_shader_object_id)
852 	{
853 		gl.deleteShader(fragment_shader_object_id);
854 		fragment_shader_object_id = 0;
855 	}
856 	if (0 != geometry_shader_object_id)
857 	{
858 		gl.deleteShader(geometry_shader_object_id);
859 		geometry_shader_object_id = 0;
860 	}
861 	if (0 != tess_ctrl_shader_object_id)
862 	{
863 		gl.deleteShader(tess_ctrl_shader_object_id);
864 		tess_ctrl_shader_object_id = 0;
865 	}
866 	if (0 != tess_eval_shader_object_id)
867 	{
868 		gl.deleteShader(tess_eval_shader_object_id);
869 		tess_eval_shader_object_id = 0;
870 	}
871 	if (0 != vertex_shader_object_id)
872 	{
873 		gl.deleteShader(vertex_shader_object_id);
874 		vertex_shader_object_id = 0;
875 	}
876 
877 	/* Return test pass if true. */
878 	if (true == test_result)
879 	{
880 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
881 	}
882 
883 	return CONTINUE;
884 }
885 
886 /** Runs the positive test.
887  *  The shader sources are considered as valid,
888  *  and the compilation and program linking are expected to succeed.
889  *
890  * @tparam API                     Tested API descriptor
891  *
892  * @param vertex_shader_source     The source for the vertex shader to be used for this test.
893  * @param fragment_shader_source   The source for the fragment shader to be used for this test.
894  * @param delete_generated_objects If true, the compiled shader objects will be deleted before returning.
895  *
896  *  @return QP_TEST_RESULT_FAIL - test has failed;
897  *          QP_TEST_RESULT_PASS - test has succeeded;
898  **/
899 template <class API>
execute_positive_test(const std::string & vertex_shader_source,const std::string & fragment_shader_source,bool delete_generated_objects,bool require_gpu_shader5)900 tcu::TestNode::IterateResult TestCaseBase<API>::execute_positive_test(const std::string& vertex_shader_source,
901 																	  const std::string& fragment_shader_source,
902 																	  bool				 delete_generated_objects,
903 																	  bool				 require_gpu_shader5)
904 {
905 	glw::GLint			  compile_status = GL_TRUE;
906 	const glw::Functions& gl			 = context_id.getRenderContext().getFunctions();
907 	glw::GLint			  link_status	= GL_TRUE;
908 	bool				  test_result	= true;
909 
910 	/* Compile, and check the compilation result for the fragment shader object. */
911 	compile_status = compile_shader_and_get_compilation_result(
912 		fragment_shader_source, TestCaseBase<API>::FRAGMENT_SHADER_TYPE, require_gpu_shader5);
913 
914 	if (compile_status == GL_FALSE)
915 	{
916 		TCU_FAIL("The fragment shader was expected to compile successfully, but failed to compile.");
917 
918 		test_result = false;
919 	}
920 
921 	/* Compile, and check the compilation result for the vertex shader object. */
922 	compile_status = compile_shader_and_get_compilation_result(
923 		vertex_shader_source, TestCaseBase<API>::VERTEX_SHADER_TYPE, require_gpu_shader5);
924 
925 	if (compile_status == GL_FALSE)
926 	{
927 		TCU_FAIL("The vertex shader was expected to compile successfully, but failed to compile.");
928 
929 		test_result = false;
930 	}
931 
932 	if (true == test_result)
933 	{
934 		/* Create program object. */
935 		assert(0 == program_object_id);
936 		program_object_id = gl.createProgram();
937 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a program object.");
938 
939 		/* Configure the program object */
940 		gl.attachShader(program_object_id, fragment_shader_object_id);
941 		gl.attachShader(program_object_id, vertex_shader_object_id);
942 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed.");
943 
944 		gl.deleteShader(fragment_shader_object_id);
945 		gl.deleteShader(vertex_shader_object_id);
946 		fragment_shader_object_id = 0;
947 		vertex_shader_object_id   = 0;
948 
949 		/* Link the program object */
950 		gl.linkProgram(program_object_id);
951 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed.");
952 
953 		/* Make sure the linking operation succeeded. */
954 		gl.getProgramiv(program_object_id, GL_LINK_STATUS, &link_status);
955 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed.");
956 
957 		if (link_status != GL_TRUE)
958 		{
959 #if IS_DEBUG
960 			glw::GLint  length = 0;
961 			std::string message;
962 
963 			/* Get error log length */
964 			gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &length);
965 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
966 
967 			message.resize(length, 0);
968 
969 			/* Get error log */
970 			gl.getProgramInfoLog(program_object_id, length, 0, &message[0]);
971 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
972 
973 			context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0]
974 												 << tcu::TestLog::EndMessage;
975 
976 #if IS_DEBUG_DUMP_ALL_SHADERS
977 #else  /* IS_DEBUG_DUMP_ALL_SHADERS */
978 			context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(vertex_shader_source);
979 			context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(fragment_shader_source);
980 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
981 #endif /* IS_DEBUG */
982 
983 			TCU_FAIL("Linking was expected to succeed, but the process was unsuccessful.");
984 
985 			test_result = false;
986 		}
987 	}
988 
989 	if (delete_generated_objects)
990 	{
991 		/* Deallocate any resources used. */
992 		this->delete_objects();
993 	}
994 
995 	/* Return test pass if true. */
996 	if (true == test_result)
997 	{
998 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
999 	}
1000 
1001 	return CONTINUE;
1002 }
1003 
1004 /** Runs the positive test.
1005  *  The shader sources are considered as valid,
1006  *  and the compilation and program linking are expected to succeed.
1007  *
1008  * @tparam API                     Tested API descriptor
1009  *
1010  * @param vertex_shader_source     The source for the vertex shader to be used for this test.
1011  * @param tess_ctrl_shader_source  The source for the vertex shader to be used for this test.
1012  * @param tess_eval_shader_source  The source for the vertex shader to be used for this test.
1013  * @param geometry_shader_source   The source for the vertex shader to be used for this test.
1014  * @param fragment_shader_source   The source for the vertex shader to be used for this test.
1015  * @param compute_shader_source    The source for the fragment shader to be used for this test.
1016  * @param delete_generated_objects If true, the compiled shader objects will be deleted before returning.
1017  *
1018  *  @return QP_TEST_RESULT_FAIL - test has failed;
1019  *          QP_TEST_RESULT_PASS - test has succeeded;
1020  **/
1021 template <class API>
execute_positive_test(const std::string & vertex_shader_source,const std::string & tess_ctrl_shader_source,const std::string & tess_eval_shader_source,const std::string & geometry_shader_source,const std::string & fragment_shader_source,const std::string & compute_shader_source,bool delete_generated_objects,bool require_gpu_shader5)1022 tcu::TestNode::IterateResult TestCaseBase<API>::execute_positive_test(
1023 	const std::string& vertex_shader_source, const std::string& tess_ctrl_shader_source,
1024 	const std::string& tess_eval_shader_source, const std::string& geometry_shader_source,
1025 	const std::string& fragment_shader_source, const std::string& compute_shader_source, bool delete_generated_objects,
1026 	bool require_gpu_shader5)
1027 {
1028 	glw::GLint			  compile_status = GL_TRUE;
1029 	const glw::Functions& gl			 = context_id.getRenderContext().getFunctions();
1030 	glw::GLint			  link_status	= GL_TRUE;
1031 	bool				  test_compute   = !compute_shader_source.empty();
1032 	bool				  test_result	= true;
1033 
1034 	if (false == test_compute)
1035 	{
1036 		/* Compile, and check the compilation result for the fragment shader object. */
1037 		compile_status = compile_shader_and_get_compilation_result(
1038 			fragment_shader_source, TestCaseBase<API>::FRAGMENT_SHADER_TYPE, require_gpu_shader5);
1039 
1040 		if (compile_status == GL_FALSE)
1041 		{
1042 			TCU_FAIL("The fragment shader was expected to compile successfully, but failed to compile.");
1043 
1044 			test_result = false;
1045 		}
1046 
1047 		/* Compile, and check the compilation result for the geometry shader object. */
1048 		compile_status = compile_shader_and_get_compilation_result(
1049 			geometry_shader_source, TestCaseBase<API>::GEOMETRY_SHADER_TYPE, require_gpu_shader5);
1050 
1051 		if (compile_status == GL_FALSE)
1052 		{
1053 			TCU_FAIL("The geometry shader was expected to compile successfully, but failed to compile.");
1054 
1055 			test_result = false;
1056 		}
1057 
1058 		/* Compile, and check the compilation result for the te shader object. */
1059 		compile_status = compile_shader_and_get_compilation_result(
1060 			tess_eval_shader_source, TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE, require_gpu_shader5);
1061 
1062 		if (compile_status == GL_FALSE)
1063 		{
1064 			TCU_FAIL("The tesselation evaluation shader was expected to compile successfully, but failed to compile.");
1065 
1066 			test_result = false;
1067 		}
1068 
1069 		/* Compile, and check the compilation result for the tc shader object. */
1070 		compile_status = compile_shader_and_get_compilation_result(
1071 			tess_ctrl_shader_source, TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE, require_gpu_shader5);
1072 
1073 		if (compile_status == GL_FALSE)
1074 		{
1075 			TCU_FAIL("The tesselation control shader was expected to compile successfully, but failed to compile.");
1076 
1077 			test_result = false;
1078 		}
1079 
1080 		/* Compile, and check the compilation result for the vertex shader object. */
1081 		compile_status = compile_shader_and_get_compilation_result(
1082 			vertex_shader_source, TestCaseBase<API>::VERTEX_SHADER_TYPE, require_gpu_shader5);
1083 
1084 		if (compile_status == GL_FALSE)
1085 		{
1086 			TCU_FAIL("The vertex shader was expected to compile successfully, but failed to compile.");
1087 
1088 			test_result = false;
1089 		}
1090 	}
1091 	else
1092 	{
1093 		/* Compile, and check the compilation result for the compute shader object. */
1094 		compile_status = compile_shader_and_get_compilation_result(
1095 			compute_shader_source, TestCaseBase<API>::COMPUTE_SHADER_TYPE, require_gpu_shader5);
1096 
1097 		if (compile_status == GL_FALSE)
1098 		{
1099 			TCU_FAIL("The compute shader was expected to compile successfully, but failed to compile.");
1100 
1101 			test_result = false;
1102 		}
1103 	}
1104 
1105 	if (true == test_result)
1106 	{
1107 		/* Create program object. */
1108 		program_object_id = gl.createProgram();
1109 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a program object.");
1110 
1111 		/* Configure the program object */
1112 		if (false == test_compute)
1113 		{
1114 			gl.attachShader(program_object_id, fragment_shader_object_id);
1115 
1116 			if (geometry_shader_object_id)
1117 			{
1118 				gl.attachShader(program_object_id, geometry_shader_object_id);
1119 			}
1120 
1121 			if (tess_ctrl_shader_object_id)
1122 			{
1123 				gl.attachShader(program_object_id, tess_ctrl_shader_object_id);
1124 			}
1125 
1126 			if (tess_eval_shader_object_id)
1127 			{
1128 				gl.attachShader(program_object_id, tess_eval_shader_object_id);
1129 			}
1130 
1131 			gl.attachShader(program_object_id, vertex_shader_object_id);
1132 		}
1133 		else
1134 		{
1135 			gl.attachShader(program_object_id, compute_shader_object_id);
1136 		}
1137 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed.");
1138 
1139 		if (false == test_compute)
1140 		{
1141 			gl.deleteShader(fragment_shader_object_id);
1142 
1143 			if (geometry_shader_object_id)
1144 			{
1145 				gl.deleteShader(geometry_shader_object_id);
1146 			}
1147 
1148 			if (tess_ctrl_shader_object_id)
1149 			{
1150 				gl.deleteShader(tess_ctrl_shader_object_id);
1151 			}
1152 
1153 			if (tess_eval_shader_object_id)
1154 			{
1155 				gl.deleteShader(tess_eval_shader_object_id);
1156 			}
1157 
1158 			gl.deleteShader(vertex_shader_object_id);
1159 		}
1160 		else
1161 		{
1162 			gl.deleteShader(compute_shader_object_id);
1163 		}
1164 
1165 		fragment_shader_object_id  = 0;
1166 		vertex_shader_object_id	= 0;
1167 		geometry_shader_object_id  = 0;
1168 		tess_ctrl_shader_object_id = 0;
1169 		tess_eval_shader_object_id = 0;
1170 		compute_shader_object_id   = 0;
1171 
1172 		/* Link the program object */
1173 		gl.linkProgram(program_object_id);
1174 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed.");
1175 
1176 		/* Make sure the linking operation succeeded. */
1177 		gl.getProgramiv(program_object_id, GL_LINK_STATUS, &link_status);
1178 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed.");
1179 
1180 		if (link_status != GL_TRUE)
1181 		{
1182 #if IS_DEBUG
1183 			glw::GLint  length = 0;
1184 			std::string message;
1185 
1186 			/* Get error log length */
1187 			gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &length);
1188 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
1189 
1190 			message.resize(length, 0);
1191 
1192 			/* Get error log */
1193 			gl.getProgramInfoLog(program_object_id, length, 0, &message[0]);
1194 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
1195 
1196 			context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0]
1197 												 << tcu::TestLog::EndMessage;
1198 
1199 #if IS_DEBUG_DUMP_ALL_SHADERS
1200 			if (false == test_compute)
1201 			{
1202 				context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(vertex_shader_source);
1203 				context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(tess_ctrl_shader_source);
1204 				context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(tess_eval_shader_source);
1205 				context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(geometry_shader_source);
1206 				context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(fragment_shader_source);
1207 			}
1208 			else
1209 			{
1210 				context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(compute_shader_source);
1211 			}
1212 #endif /* IS_DEBUG_DUMP_ALL_SHADERS */
1213 #endif /* IS_DEBUG */
1214 
1215 			TCU_FAIL("Linking was expected to succeed, but the process was unsuccessful.");
1216 
1217 			test_result = false;
1218 		}
1219 	}
1220 
1221 	if (delete_generated_objects)
1222 	{
1223 		/* Deallocate any resources used. */
1224 		this->delete_objects();
1225 	}
1226 
1227 	/* Return test pass if true. */
1228 	if (true == test_result)
1229 	{
1230 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1231 	}
1232 
1233 	return CONTINUE;
1234 }
1235 
1236 /** Adds the specified @param sub_script onto the base_string @param number_of_elements times.
1237  *  E.g. extend_string("a", [2], 3) would give a[2][2][2].
1238  *
1239  * @tparam API               Tested API descriptor
1240  *
1241  * @param base_string        The base string that is to be added to.
1242  * @param sub_string         The string to be repeatedly added
1243  * @param number_of_elements The number of repetitions.
1244  *
1245  *  @return The extended string.
1246  **/
1247 template <class API>
extend_string(std::string base_string,std::string sub_string,size_t number_of_elements)1248 std::string TestCaseBase<API>::extend_string(std::string base_string, std::string sub_string, size_t number_of_elements)
1249 {
1250 	std::string temp_string = base_string;
1251 
1252 	for (size_t sub_script_index = 0; sub_script_index < number_of_elements; sub_script_index++)
1253 	{
1254 		temp_string += sub_string;
1255 	}
1256 
1257 	return temp_string;
1258 }
1259 
1260 /* Generates the shader source code for the SizedDeclarationsPrimitive
1261  * array tests, and attempts to compile each test shader, for both
1262  * vertex and fragment shaders.
1263  *
1264  * @tparam API               Tested API descriptor
1265  *
1266  * @param tested_shader_type The type of shader that is being tested
1267  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1268  *
1269  **/
1270 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1271 void SizedDeclarationsPrimitive<API>::test_shader_compilation(
1272 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1273 {
1274 	for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
1275 	{
1276 		_supported_variable_types_map_const_iterator var_iterator =
1277 			supported_variable_types_map.find(API::var_types[var_type_index]);
1278 
1279 		if (var_iterator != supported_variable_types_map.end())
1280 		{
1281 			/* Loop round for each var_types ("int", "uint", "float", etc.)
1282 			 * We are testing a[][] to a [][][][][][][][], so start counter at 2. */
1283 			for (size_t max_dimension_limit = 2; max_dimension_limit <= API::MAX_ARRAY_DIMENSIONS;
1284 				 max_dimension_limit++)
1285 			{
1286 				// Record the base varTypeModifier + varType
1287 				std::string base_var_type		 = var_iterator->second.type;
1288 				std::string base_variable_string = base_var_type;
1289 
1290 				for (size_t base_sub_script_index = 0; base_sub_script_index <= max_dimension_limit;
1291 					 base_sub_script_index++)
1292 				{
1293 					std::string shader_source = "";
1294 
1295 					// Add the shader body start, and the base varTypeModifier + varType + variable name.
1296 					shader_source += shader_start + "    " + base_variable_string + " a";
1297 
1298 					for (size_t remaining_sub_script_index = base_sub_script_index;
1299 						 remaining_sub_script_index < max_dimension_limit; remaining_sub_script_index++)
1300 					{
1301 						/* Add as many array sub_scripts as we can, up to the current dimension limit. */
1302 						shader_source += "[2]";
1303 					}
1304 
1305 					/* End line */
1306 					shader_source += ";\n";
1307 
1308 					/* End main */
1309 					DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1310 
1311 					/* Execute test */
1312 					EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1313 
1314 					/* From now on, we'll have an extra sub_script each time. */
1315 					base_variable_string += "[2]";
1316 				} /* for (int base_sub_script_index = 0; ...) */
1317 			}	 /* for (int max_dimension_limit = 2; ...) */
1318 		}		  /* if var_type iterator found */
1319 		else
1320 		{
1321 			TCU_FAIL("Type not found.");
1322 		}
1323 	} /* for (int var_type_index = 0; ...) */
1324 }
1325 
1326 /* Generates the shader source code for the SizedDeclarationsStructTypes1
1327  * array tests, and attempts to compile each test shader, for both
1328  * vertex and fragment shaders.
1329  *
1330  * @tparam API               Tested API descriptor
1331  *
1332  * @param tested_shader_type The type of shader that is being tested
1333  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1334  */
1335 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1336 void SizedDeclarationsStructTypes1<API>::test_shader_compilation(
1337 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1338 {
1339 	std::string example_struct("struct light {\n"
1340 							   "    float intensity;\n"
1341 							   "    int   position;\n"
1342 							   "};\n\n");
1343 	std::string shader_source;
1344 
1345 	for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1346 	{
1347 		shader_source = example_struct;
1348 		shader_source += shader_start;
1349 		shader_source += "    light[2]";
1350 
1351 		for (size_t temp_dimension_index = 0; temp_dimension_index < max_dimension_index; temp_dimension_index++)
1352 		{
1353 			shader_source += "[2]";
1354 		}
1355 
1356 		shader_source += " x;\n";
1357 
1358 		/* End main */
1359 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1360 
1361 		/* Execute test */
1362 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1363 
1364 	} /* for (int max_dimension_index = 1; ...) */
1365 }
1366 
1367 /* Generates the shader source code for the SizedDeclarationsStructTypes2
1368  * array tests, and attempts to compile each test shader, for both
1369  * vertex and fragment shaders.
1370  *
1371  * @tparam API               Tested API descriptor
1372  *
1373  * @param tested_shader_type The type of shader that is being tested
1374  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1375  */
1376 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1377 void SizedDeclarationsStructTypes2<API>::test_shader_compilation(
1378 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1379 {
1380 	std::string structure_declaration = "struct MyStructure {\n"
1381 										"   float a[2], "
1382 										"b[2][2], "
1383 										"c[2][2][2], "
1384 										"d[2][2][2][2], "
1385 										"e[2][2][2][2][2], "
1386 										"f[2][2][2][2][2][2], "
1387 										"g[2][2][2][2][2][2][2], "
1388 										"h[2][2][2][2][2][2][2][2];\n"
1389 										"} myStructureObject;\n\n";
1390 	std::string shader_source = structure_declaration;
1391 
1392 	shader_source += shader_start;
1393 
1394 	/* End main */
1395 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1396 
1397 	/* Execute test */
1398 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1399 }
1400 
1401 /* Generates the shader source code for the SizedDeclarationsStructTypes3
1402  * array tests, and attempts to compile each test shader, for both
1403  * vertex and fragment shaders.
1404  *
1405  * @tparam API               Tested API descriptor
1406  *
1407  * @param tested_shader_type The type of shader that is being tested
1408  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1409  */
1410 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1411 void SizedDeclarationsStructTypes3<API>::test_shader_compilation(
1412 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1413 {
1414 	std::string example_struct("struct light {\n"
1415 							   "    float[2] intensity;\n"
1416 							   "    int[2] position;\n"
1417 							   "};\n");
1418 	std::string shader_source;
1419 
1420 	for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1421 	{
1422 		shader_source = example_struct;
1423 		shader_source += shader_start;
1424 		shader_source += this->extend_string("    light my_light_object", "[2]", max_dimension_index);
1425 		shader_source += ";\n";
1426 
1427 		/* End main */
1428 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1429 
1430 		/* Execute test */
1431 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1432 	} /* for (int max_dimension_index = 1; ...) */
1433 }
1434 
1435 /* Generates the shader source code for the SizedDeclarationsStructTypes4
1436  * array tests, and attempts to compile each test shader, for both
1437  * vertex and fragment shaders.
1438  *
1439  * @tparam API               Tested API descriptor
1440  *
1441  * @param tested_shader_type The type of shader that is being tested
1442  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1443  */
1444 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1445 void SizedDeclarationsStructTypes4<API>::test_shader_compilation(
1446 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1447 {
1448 	std::string example_struct("struct light {\n"
1449 							   "    float[2] intensity;\n"
1450 							   "    int[2] position;\n"
1451 							   "} lightVar[2]");
1452 	std::string shader_source;
1453 
1454 	for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1455 	{
1456 		shader_source = example_struct;
1457 
1458 		for (size_t temp_dimension_index = 0; temp_dimension_index < max_dimension_index; temp_dimension_index++)
1459 		{
1460 			shader_source += "[2]";
1461 		}
1462 		shader_source += ";\n\n";
1463 		shader_source += shader_start;
1464 
1465 		/* End main */
1466 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1467 
1468 		/* Execute test */
1469 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1470 	} /* for (int max_dimension_index = 1; ...) */
1471 }
1472 
1473 /* Generates the shader source code for the SizedDeclarationsTypenameStyle1
1474  * array tests, and attempts to compile each test shader, for both
1475  * vertex and fragment shaders.
1476  *
1477  * @tparam API               Tested API descriptor
1478  *
1479  * @param tested_shader_type The type of shader that is being tested
1480  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1481  */
1482 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1483 void SizedDeclarationsTypenameStyle1<API>::test_shader_compilation(
1484 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1485 {
1486 	for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1487 	{
1488 		std::string shader_source = shader_start;
1489 
1490 		shader_source += this->extend_string("    float", "[2]", max_dimension_index);
1491 		shader_source += this->extend_string(" x", "[2]", API::MAX_ARRAY_DIMENSIONS - max_dimension_index);
1492 		shader_source += ";\n";
1493 
1494 		/* End main */
1495 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1496 
1497 		/* Execute test */
1498 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1499 	} /* for (int max_dimension_index = 1; ...) */
1500 }
1501 
1502 /* Generates the shader source code for the SizedDeclarationsTypenameStyle2
1503  * array tests, and attempts to compile each test shader, for both
1504  * vertex and fragment shaders.
1505  *
1506  * @tparam API               Tested API descriptor
1507  *
1508  * @param tested_shader_type The type of shader that is being tested
1509  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1510  */
1511 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1512 void SizedDeclarationsTypenameStyle2<API>::test_shader_compilation(
1513 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1514 {
1515 	std::string shader_source = shader_start;
1516 
1517 	shader_source += this->extend_string("    float", "[2]", 2);
1518 	shader_source += this->extend_string(" a", "[2]", 0);
1519 	shader_source += ", ";
1520 	shader_source += this->extend_string("b", "[2]", 1);
1521 	shader_source += ", ";
1522 	shader_source += this->extend_string("c", "[2]", 2);
1523 	shader_source += ", ";
1524 	shader_source += this->extend_string("d", "[2]", 3);
1525 	shader_source += ", ";
1526 	shader_source += this->extend_string("e", "[2]", 4);
1527 	shader_source += ", ";
1528 	shader_source += this->extend_string("f", "[2]", 5);
1529 	shader_source += ", ";
1530 	shader_source += this->extend_string("g", "[2]", 6);
1531 	shader_source += ";\n";
1532 
1533 	/* End main */
1534 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1535 
1536 	/* Execute test */
1537 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1538 }
1539 
1540 /* Generates the shader source code for the SizedDeclarationsTypenameStyle3
1541  * array tests, and attempts to compile each test shader, for both
1542  * vertex and fragment shaders.
1543  *
1544  * @tparam API               Tested API descriptor
1545  *
1546  * @param tested_shader_type The type of shader that is being tested
1547  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1548  */
1549 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1550 void SizedDeclarationsTypenameStyle3<API>::test_shader_compilation(
1551 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1552 {
1553 	std::string shader_source = "struct{\n" + this->extend_string("    float", "[2]", 2);
1554 
1555 	shader_source += this->extend_string(" a", "[2]", API::MAX_ARRAY_DIMENSIONS - API::MAX_ARRAY_DIMENSIONS);
1556 	shader_source += ",";
1557 	shader_source += this->extend_string("    b", "[2]", 1);
1558 	shader_source += ",";
1559 	shader_source += this->extend_string("    c", "[2]", 2);
1560 	shader_source += ",";
1561 	shader_source += this->extend_string("    d", "[2]", 3);
1562 	shader_source += ",";
1563 	shader_source += this->extend_string("    e", "[2]", 4);
1564 	shader_source += ",";
1565 	shader_source += this->extend_string("    f", "[2]", 5);
1566 	shader_source += ",";
1567 	shader_source += this->extend_string("    g", "[2]", 6);
1568 	shader_source += ";\n} x;\n\n";
1569 	shader_source += shader_start;
1570 
1571 	/* End main */
1572 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1573 
1574 	/* Execute test */
1575 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1576 }
1577 
1578 /* Generates the shader source code for the SizedDeclarationsTypenameStyle4
1579  * array tests, and attempts to compile each test shader, for both
1580  * vertex and fragment shaders.
1581  *
1582  * @tparam API               Tested API descriptor
1583  *
1584  * @param tested_shader_type The type of shader that is being tested
1585  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1586  */
1587 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1588 void SizedDeclarationsTypenameStyle4<API>::test_shader_compilation(
1589 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1590 {
1591 	std::string example_struct_begin("struct light {\n");
1592 	std::string example_struct_end("};\n\n");
1593 
1594 	for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1595 	{
1596 		std::string shader_source = example_struct_begin;
1597 
1598 		shader_source += this->extend_string("    float", "[2]", max_dimension_index);
1599 		shader_source += this->extend_string(" x", "[2]", API::MAX_ARRAY_DIMENSIONS - max_dimension_index);
1600 		shader_source += ";\n";
1601 		shader_source += example_struct_end;
1602 		shader_source += shader_start;
1603 
1604 		/* End main */
1605 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1606 
1607 		/* Execute test */
1608 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1609 	} /* for (int max_dimension_index = 1; ...) */
1610 }
1611 
1612 /* Generates the shader source code for the SizedDeclarationsTypenameStyle5
1613  * array tests, and attempts to compile each test shader, for both
1614  * vertex and fragment shaders.
1615  *
1616  * @tparam API               Tested API descriptor
1617  *
1618  * @param tested_shader_type The type of shader that is being tested
1619  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1620  */
1621 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1622 void SizedDeclarationsTypenameStyle5<API>::test_shader_compilation(
1623 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1624 {
1625 	std::string example_struct_begin("struct light {\n");
1626 	std::string example_struct_end("};\n\n");
1627 
1628 	std::string shader_source = example_struct_begin;
1629 
1630 	shader_source += this->extend_string("    float", "[2]", 2);
1631 	shader_source += this->extend_string(" a", "[2]", API::MAX_ARRAY_DIMENSIONS - API::MAX_ARRAY_DIMENSIONS);
1632 	shader_source += ", ";
1633 	shader_source += this->extend_string("b", "[2]", 2);
1634 	shader_source += ", ";
1635 	shader_source += this->extend_string("c", "[2]", 3);
1636 	shader_source += ", ";
1637 	shader_source += this->extend_string("d", "[2]", 4);
1638 	shader_source += ", ";
1639 	shader_source += this->extend_string("e", "[2]", 5);
1640 	shader_source += ", ";
1641 	shader_source += this->extend_string("f", "[2]", 6);
1642 	shader_source += ";\n";
1643 	shader_source += example_struct_end;
1644 	shader_source += shader_start;
1645 
1646 	/* End main */
1647 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1648 
1649 	/* Execute test */
1650 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1651 }
1652 
1653 /* Generates the shader source code for the SizedDeclarationsFunctionParams
1654  * array tests, and attempts to compile each test shader, for both
1655  * vertex and fragment shaders.
1656  *
1657  * @tparam API               Tested API descriptor
1658  *
1659  * @param tested_shader_type The type of shader that is being tested
1660  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1661  */
1662 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1663 void SizedDeclarationsFunctionParams<API>::test_shader_compilation(
1664 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1665 {
1666 	size_t		dimension_index = 0;
1667 	std::string example_struct1("\nvoid my_function(");
1668 	std::string example_struct2(")\n"
1669 								"{\n"
1670 								"}\n\n");
1671 	std::string base_variable_string;
1672 	std::string variable_basenames[API::MAX_ARRAY_DIMENSIONS] = { "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8" };
1673 	std::string full_variable_names[API::MAX_ARRAY_DIMENSIONS];
1674 
1675 	for (size_t max_dimension_index = 0; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1676 	{
1677 		full_variable_names[max_dimension_index] =
1678 			this->extend_string(variable_basenames[max_dimension_index], "[2]", max_dimension_index + 1);
1679 	}
1680 
1681 	for (size_t max_dimension_index = 0; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1682 	{
1683 		base_variable_string += "float ";
1684 		base_variable_string += full_variable_names[max_dimension_index];
1685 		base_variable_string += ";\n";
1686 	}
1687 
1688 	base_variable_string += example_struct1;
1689 	base_variable_string += this->extend_string("float a", "[2]", 1);
1690 	base_variable_string += ", ";
1691 	base_variable_string += this->extend_string("float b", "[2]", 2);
1692 	base_variable_string += ", ";
1693 	base_variable_string += this->extend_string("float c", "[2]", 3);
1694 	base_variable_string += ", ";
1695 	base_variable_string += this->extend_string("float d", "[2]", 4);
1696 	base_variable_string += ", ";
1697 	base_variable_string += this->extend_string("float e", "[2]", 5);
1698 	base_variable_string += ", ";
1699 	base_variable_string += this->extend_string("float f", "[2]", 6);
1700 	base_variable_string += ", ";
1701 	base_variable_string += this->extend_string("float g", "[2]", 7);
1702 	base_variable_string += ", ";
1703 	base_variable_string += this->extend_string("float h", "[2]", 8);
1704 	base_variable_string += example_struct2;
1705 
1706 	std::string shader_source = base_variable_string;
1707 
1708 	shader_source += shader_start;
1709 	shader_source += "    my_function(";
1710 
1711 	for (dimension_index = 0; dimension_index < API::MAX_ARRAY_DIMENSIONS - 1; dimension_index++)
1712 	{
1713 		shader_source += variable_basenames[dimension_index];
1714 		shader_source += ", ";
1715 	}
1716 
1717 	shader_source += variable_basenames[dimension_index];
1718 	shader_source += ");\n";
1719 
1720 	/* End main */
1721 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1722 
1723 	/* Execute test */
1724 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
1725 
1726 	/* Only the previous case should succeed, so start from index 1 rather than 0.
1727 	 * The other cases should fail, so only compile them, rather than trying to also link them.
1728 	 * We'll swap items 2/3, then 2/4, then 2/5, then 2/6, ...
1729 	 * Then we'll swap items 3/4, then 3/5, ...
1730 	 * Repeat, starting for 4/5-8, 5/6-8, 6/7-8...
1731 	 * Finally, we'll swap items 7/8
1732 	 */
1733 	for (size_t swap_item = 1; swap_item < API::MAX_ARRAY_DIMENSIONS; swap_item++)
1734 	{
1735 		for (size_t max_dimension_index = swap_item + 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS;
1736 			 max_dimension_index++)
1737 		{
1738 			std::string temp = variable_basenames[swap_item];
1739 
1740 			shader_source							= base_variable_string;
1741 			variable_basenames[swap_item]			= variable_basenames[max_dimension_index];
1742 			variable_basenames[max_dimension_index] = temp;
1743 
1744 			shader_source += shader_start;
1745 			shader_source += "    my_function(";
1746 
1747 			for (dimension_index = 0; dimension_index < API::MAX_ARRAY_DIMENSIONS - 1; dimension_index++)
1748 			{
1749 				shader_source += variable_basenames[dimension_index];
1750 				shader_source += ", ";
1751 			}
1752 
1753 			shader_source += variable_basenames[dimension_index];
1754 			shader_source += ");\n";
1755 
1756 			temp									= variable_basenames[swap_item];
1757 			variable_basenames[swap_item]			= variable_basenames[max_dimension_index];
1758 			variable_basenames[max_dimension_index] = temp;
1759 
1760 			/* End main */
1761 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1762 
1763 			/* Execute test */
1764 			this->execute_negative_test(tested_shader_type, shader_source);
1765 		} /* for (int max_dimension_index = swap_item + 1; ...) */
1766 	}	 /* for (int swap_item = 1; ...) */
1767 }
1768 
1769 /* Generates the shader source code for the sized_declarations_invalid_sizes1
1770  * array tests, and attempts to compile each test shader, for both
1771  * vertex and fragment shaders.
1772  *
1773  * @tparam API               Tested API descriptor
1774  *
1775  * @param tested_shader_type The type of shader that is being tested
1776  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1777  */
1778 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1779 void sized_declarations_invalid_sizes1<API>::test_shader_compilation(
1780 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1781 {
1782 	std::string invalid_declarations[] = {
1783 		"float x[2][2][2][0];\n", "float x[2][2][0][2];\n", "float x[2][0][2][2];\n", "float x[0][2][2][2];\n",
1784 		"float x[2][2][0][0];\n", "float x[2][0][2][0];\n", "float x[0][2][2][0];\n", "float x[2][0][0][2];\n",
1785 		"float x[0][2][0][2];\n", "float x[0][0][2][2];\n", "float x[2][0][0][0];\n", "float x[0][2][0][0];\n",
1786 		"float x[0][0][2][0];\n", "float x[0][0][0][2];\n", "float x[0][0][0][0];\n"
1787 	};
1788 
1789 	for (size_t invalid_declarations_index = 0;
1790 		 invalid_declarations_index < DE_LENGTH_OF_ARRAY(invalid_declarations);
1791 		 invalid_declarations_index++)
1792 	{
1793 		std::string shader_source;
1794 
1795 		shader_source = shader_start;
1796 		shader_source += invalid_declarations[invalid_declarations_index];
1797 
1798 		/* End main */
1799 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1800 
1801 		/* Execute test */
1802 		this->execute_negative_test(tested_shader_type, shader_source);
1803 	} /* for (int invalid_declarations_index = 0; ...) */
1804 }
1805 
1806 /* Generates the shader source code for the sized_declarations_invalid_sizes2
1807  * array tests, and attempts to compile each test shader, for both
1808  * vertex and fragment shaders.
1809  *
1810  * @tparam API               Tested API descriptor
1811  *
1812  * @param tested_shader_type The type of shader that is being tested
1813  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1814  */
1815 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1816 void sized_declarations_invalid_sizes2<API>::test_shader_compilation(
1817 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1818 {
1819 	std::string invalid_declarations[] = {
1820 		"    float x[2][2][2][-1];\n",   "    float x[2][2][-1][2];\n",   "    float x[2][-1][2][2];\n",
1821 		"    float x[-1][2][2][2];\n",   "    float x[2][2][-1][-1];\n",  "    float x[2][-1][2][-1];\n",
1822 		"    float x[-1][2][2][-1];\n",  "    float x[2][-1][-1][2];\n",  "    float x[-1][2][-1][2];\n",
1823 		"    float x[-1][-1][2][2];\n",  "    float x[2][-1][-1][-1];\n", "    float x[-1][2][-1][-1];\n",
1824 		"    float x[-1][-1][2][-1];\n", "    float x[-1][-1][-1][2];\n", "    float x[-1][-1][-1][-1];\n"
1825 	};
1826 
1827 	for (size_t invalid_declarations_index = 0;
1828 		 invalid_declarations_index < DE_LENGTH_OF_ARRAY(invalid_declarations);
1829 		 invalid_declarations_index++)
1830 	{
1831 		std::string shader_source;
1832 
1833 		shader_source = shader_start;
1834 		shader_source += invalid_declarations[invalid_declarations_index];
1835 
1836 		/* End main */
1837 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1838 
1839 		/* Execute test */
1840 		this->execute_negative_test(tested_shader_type, shader_source);
1841 	} /* for (int invalid_declarations_index = 0; ...) */
1842 }
1843 
1844 /* Generates the shader source code for the sized_declarations_invalid_sizes3
1845  * array tests, and attempts to compile each test shader, for both
1846  * vertex and fragment shaders.
1847  *
1848  * @tparam API               Tested API descriptor
1849  *
1850  * @param tested_shader_type The type of shader that is being tested
1851  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1852  */
1853 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1854 void sized_declarations_invalid_sizes3<API>::test_shader_compilation(
1855 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1856 {
1857 	std::string invalid_declarations[] = {
1858 		"    float x[2][2][2][a];\n", "    float x[2][2][a][2];\n", "    float x[2][a][2][2];\n",
1859 		"    float x[a][2][2][2];\n", "    float x[2][2][a][a];\n", "    float x[2][a][2][a];\n",
1860 		"    float x[a][2][2][a];\n", "    float x[2][a][a][2];\n", "    float x[a][2][a][2];\n",
1861 		"    float x[a][a][2][2];\n", "    float x[2][a][a][a];\n", "    float x[a][2][a][a];\n",
1862 		"    float x[a][a][2][a];\n", "    float x[a][a][a][2];\n", "    float x[a][a][a][a];\n"
1863 	};
1864 	std::string non_constant_variable_declaration = "    uint a = 2u;\n";
1865 
1866 	for (size_t invalid_declarations_index = 0;
1867 		 invalid_declarations_index < DE_LENGTH_OF_ARRAY(invalid_declarations);
1868 		 invalid_declarations_index++)
1869 	{
1870 		std::string shader_source;
1871 
1872 		shader_source = shader_start;
1873 		shader_source += non_constant_variable_declaration;
1874 		shader_source += invalid_declarations[invalid_declarations_index];
1875 
1876 		/* End main */
1877 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1878 
1879 		/* Execute test */
1880 		this->execute_negative_test(tested_shader_type, shader_source);
1881 	} /* for (int invalid_declarations_index = 0; ...) */
1882 }
1883 
1884 /* Generates the shader source code for the sized_declarations_invalid_sizes4
1885  * array tests, and attempts to compile each test shader, for both
1886  * vertex and fragment shaders.
1887  *
1888  * @tparam API               Tested API descriptor
1889  *
1890  * @param tested_shader_type The type of shader that is being tested
1891  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1892  */
1893 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1894 void sized_declarations_invalid_sizes4<API>::test_shader_compilation(
1895 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1896 {
1897 	std::string input[] = { "    float x[2,2][2][2];\n", "    float x[2][2,2][2];\n", "    float x[2][2][2,2];\n",
1898 							"    float x[2,2,2][2];\n",  "    float x[2][2,2,2];\n",  "    float x[2,2,2,2];\n" };
1899 
1900 	for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
1901 	{
1902 		std::string shader_source;
1903 
1904 		shader_source += shader_start;
1905 		shader_source += input[string_index];
1906 
1907 		/* End main */
1908 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1909 
1910 		/* Execute test */
1911 		this->execute_negative_test(tested_shader_type, shader_source);
1912 	} /* for (int string_index = 0; ...) */
1913 }
1914 
1915 /* Constructs a suitable constructor for the specified number of dimensions.
1916  *
1917  * @tparam API            Tested API descriptor
1918  *
1919  * @param var_type        The type of the variable
1920  * @param dimension_index The current recursion level (counts down)
1921  * @param init_string     The initialisation string
1922  */
1923 template <class API>
recursively_initialise(std::string var_type,size_t dimension_index,std::string init_string)1924 std::string ConstructorsAndUnsizedDeclConstructors1<API>::recursively_initialise(std::string var_type,
1925 																				 size_t		 dimension_index,
1926 																				 std::string init_string)
1927 {
1928 	std::string temp_string;
1929 
1930 	if (dimension_index == 0)
1931 	{
1932 		temp_string = init_string;
1933 	}
1934 	else
1935 	{
1936 		std::string prefix = "\n";
1937 
1938 		for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
1939 		{
1940 			prefix += "    ";
1941 		}
1942 
1943 		prefix += this->extend_string(var_type, "[]", dimension_index);
1944 		prefix += "(";
1945 		for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
1946 		{
1947 			temp_string += prefix;
1948 			temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
1949 			prefix = ", ";
1950 			if (sub_script_index == 1)
1951 			{
1952 				break;
1953 			}
1954 		}
1955 		temp_string += ")";
1956 	}
1957 
1958 	return temp_string;
1959 }
1960 
1961 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructors1
1962  * array tests, and attempts to compile each test shader, for both
1963  * vertex and fragment shaders.
1964  *
1965  * @tparam API               Tested API descriptor
1966  *
1967  * @param tested_shader_type The type of shader that is being tested
1968  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
1969  */
1970 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)1971 void ConstructorsAndUnsizedDeclConstructors1<API>::test_shader_compilation(
1972 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
1973 {
1974 	//vec4 color = vec4(0.0, 1.0, 0.0, 1.0);
1975 	int num_var_types = API::n_var_types;
1976 
1977 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
1978 	{
1979 		_supported_variable_types_map_const_iterator var_iterator =
1980 			supported_variable_types_map.find(API::var_types[var_type_index]);
1981 
1982 		if (var_iterator != supported_variable_types_map.end())
1983 		{
1984 			for (size_t max_dimension_index = 2; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
1985 			{
1986 				std::string base_variable_string =
1987 					this->extend_string("    " + var_iterator->second.type + " a", "[]", max_dimension_index);
1988 
1989 				base_variable_string += " = ";
1990 				base_variable_string += recursively_initialise(var_iterator->second.type, max_dimension_index,
1991 															   var_iterator->second.initializer_with_ones);
1992 				base_variable_string += ";\n\n";
1993 
1994 				std::string shader_source = shader_start + base_variable_string;
1995 
1996 				/* End main */
1997 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
1998 
1999 				/* Execute test */
2000 				EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2001 			} /* for (int max_dimension_index = 1; ...) */
2002 		}	 /* if var_type iterator found */
2003 		else
2004 		{
2005 			TCU_FAIL("Type not found.");
2006 		}
2007 	} /* for (int var_type_index = 0; ...) */
2008 
2009 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2010 	{
2011 		_supported_variable_types_map_const_iterator var_iterator =
2012 			supported_variable_types_map.find(API::var_types[var_type_index]);
2013 
2014 		if (var_iterator != supported_variable_types_map.end())
2015 		{
2016 			std::string base_structure = "struct my_structure\n";
2017 
2018 			base_structure += "{\n";
2019 			base_structure += "    " + var_iterator->second.type + " b;\n";
2020 			base_structure += "    " + var_iterator->second.type + " c;\n";
2021 			base_structure += "};\n\n";
2022 
2023 			for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2024 			{
2025 				std::string outer_separator = "(";
2026 				std::string base_variable_string;
2027 
2028 				base_variable_string +=
2029 					this->extend_string("    " + var_iterator->second.type + " a", "[2]", max_dimension_index);
2030 				base_variable_string += " = ";
2031 				base_variable_string += recursively_initialise(var_iterator->second.type, max_dimension_index,
2032 															   var_iterator->second.initializer_with_ones);
2033 				base_variable_string += ";\n\n";
2034 
2035 				std::string shader_source = base_structure + shader_start + base_variable_string;
2036 
2037 				/* End main */
2038 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2039 
2040 				/* Execute test */
2041 				EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2042 			} /* for (int max_dimension_index = 1; ...) */
2043 		}	 /* if var_type iterator found */
2044 		else
2045 		{
2046 			TCU_FAIL("Type not found.");
2047 		}
2048 	} /* for (int var_type_index = 0; ...) */
2049 }
2050 
2051 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructors2
2052  * array tests, and attempts to compile each test shader, for both
2053  * vertex and fragment shaders.
2054  *
2055  * @tparam API               Tested API descriptor
2056  *
2057  * @param tested_shader_type The type of shader that is being tested
2058  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2059  */
2060 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2061 void ConstructorsAndUnsizedDeclConstructors2<API>::test_shader_compilation(
2062 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2063 {
2064 	std::string base_variable_string = "    float[2][2] x = float[2][2](float[4](1.0, 2.0, 3.0, 4.0));\n";
2065 	std::string shader_source		 = shader_start + base_variable_string;
2066 
2067 	/* End main */
2068 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2069 
2070 	/* Execute test */
2071 	this->execute_negative_test(tested_shader_type, shader_source);
2072 
2073 	base_variable_string = "float[2][2] x = float[2][2](float[1][4](float[4](1.0, 2.0, 3.0, 4.0)));\n\n";
2074 	shader_source		 = base_variable_string + shader_start;
2075 
2076 	/* End main */
2077 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2078 
2079 	/* Execute test */
2080 	this->execute_negative_test(tested_shader_type, shader_source);
2081 }
2082 
2083 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedConstructors
2084  * array tests, and attempts to compile each test shader, for both
2085  * vertex and fragment shaders.
2086  *
2087  * @tparam API               Tested API descriptor
2088  *
2089  * @param tested_shader_type The type of shader that is being tested
2090  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2091  */
2092 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2093 void ConstructorsAndUnsizedDeclUnsizedConstructors<API>::test_shader_compilation(
2094 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2095 {
2096 	std::string shader_variable_declarations = "= float[2][1][2][1](\n"
2097 											   "        float[1][2][1](\n"
2098 											   "            float[2][1]( \n"
2099 											   "                float[1](12.3), float[1](54.2) \n"
2100 											   "            )\n"
2101 											   "        ),\n"
2102 											   "        float[1][2][1](\n"
2103 											   "            float[2][1]( \n"
2104 											   "                float[1]( 3.2), float[1]( 7.4) \n"
2105 											   "            )\n"
2106 											   "        )\n"
2107 											   "    );\n\n";
2108 
2109 	std::string input[] = { "float a[2][1][2][]", "float a[2][1][][1]", "float a[2][1][][]", "float a[2][][2][1]",
2110 							"float a[2][][2][]",  "float a[2][][][1]",  "float a[2][][][]",  "float a[][1][2][1]",
2111 							"float a[][1][2][]",  "float a[][1][][1]",  "float a[][1][][]",  "float a[][][2][1]",
2112 							"float a[][][2][]",   "float a[][][][1]",   "float a[][][][]" };
2113 
2114 	for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
2115 	{
2116 		std::string shader_source = shader_start + "    " + input[string_index] + shader_variable_declarations;
2117 
2118 		/* End main */
2119 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2120 
2121 		/* Execute test */
2122 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2123 	} /* for (int string_index = 0; ...) */
2124 }
2125 
2126 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConst
2127  * array tests, and attempts to compile each test shader, for both
2128  * vertex and fragment shaders.
2129  *
2130  * @tparam API               Tested API descriptor
2131  *
2132  * @param tested_shader_type The type of shader that is being tested
2133  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2134  */
2135 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2136 void ConstructorsAndUnsizedDeclConst<API>::test_shader_compilation(
2137 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2138 {
2139 	std::string shader_source = "const float[2][2] x = float[2][2](float[2](1.0, 2.0), float[2](3.0, 4.0));\n\n";
2140 	shader_source += shader_start;
2141 
2142 	/* End main */
2143 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2144 
2145 	/* Execute test */
2146 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2147 }
2148 
2149 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors1
2150  * array tests, and attempts to compile each test shader, for both
2151  * vertex and fragment shaders.
2152  *
2153  * @tparam API               Tested API descriptor
2154  *
2155  * @param tested_shader_type The type of shader that is being tested
2156  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2157  */
2158 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2159 void ConstructorsAndUnsizedDeclInvalidConstructors1<API>::test_shader_compilation(
2160 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2161 {
2162 	int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
2163 
2164 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2165 	{
2166 		_supported_variable_types_map_const_iterator var_iterator =
2167 			supported_variable_types_map.find(opaque_var_types[var_type_index]);
2168 
2169 		if (var_iterator != supported_variable_types_map.end())
2170 		{
2171 			std::string base_variable_string =
2172 				"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler1;\n" +
2173 				"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler2;\n" +
2174 				"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler3;\n" +
2175 				"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler4;\n\n";
2176 
2177 			std::string shader_source = base_variable_string + shader_start;
2178 			shader_source += "    const " + var_iterator->second.type + "[2][2] x = " + var_iterator->second.type +
2179 							 "[2][2](" + var_iterator->second.type + "[2](my_sampler1, my_sampler2), " +
2180 							 var_iterator->second.type + "[2](my_sampler3, my_sampler4));\n\n";
2181 
2182 			/* End main */
2183 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2184 
2185 			/* Execute test */
2186 			this->execute_negative_test(tested_shader_type, shader_source);
2187 		} /* if var_type iterator found */
2188 		else
2189 		{
2190 			TCU_FAIL("Type not found.");
2191 		}
2192 	} /* for (int var_type_index = 0; ...) */
2193 }
2194 
2195 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors2
2196  * array tests, and attempts to compile each test shader, for both
2197  * vertex and fragment shaders.
2198  *
2199  * @tparam API               Tested API descriptor
2200  *
2201  * @param tested_shader_type The type of shader that is being tested
2202  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2203  */
2204 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2205 void ConstructorsAndUnsizedDeclInvalidConstructors2<API>::test_shader_compilation(
2206 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2207 {
2208 	std::string invalid_initializers[] = { "    int x[2][2][0]; \n", "    int x[2][0][2]; \n", "    int x[0][2][2]; \n",
2209 										   "    int x[2][0][0]; \n", "    int x[0][2][0]; \n", "    int x[0][0][2]; \n",
2210 										   "    int x[0][0][0]; \n" };
2211 
2212 	for (size_t invalid_initializers_index = 0;
2213 		 invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]);
2214 		 invalid_initializers_index++)
2215 	{
2216 		std::string shader_source;
2217 
2218 		shader_source = shader_start;
2219 		shader_source += invalid_initializers[invalid_initializers_index];
2220 
2221 		/* End main */
2222 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2223 
2224 		/* Execute test */
2225 		this->execute_negative_test(tested_shader_type, shader_source);
2226 	} /* for (int invalid_initializers_index = 0; ...) */
2227 }
2228 
2229 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors3
2230  * array tests, and attempts to compile each test shader, for both
2231  * vertex and fragment shaders.
2232  *
2233  * @tparam API               Tested API descriptor
2234  *
2235  * @param tested_shader_type The type of shader that is being tested
2236  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2237  */
2238 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2239 void ConstructorsAndUnsizedDeclInvalidConstructors3<API>::test_shader_compilation(
2240 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2241 {
2242 	std::string invalid_initializers[] = { "    int x[2][2][-1]; \n",  "    int x[2][-1][2]; \n",
2243 										   "    int x[-1][2][2]; \n",  "    int x[2][-1][-1]; \n",
2244 										   "    int x[-1][2][-1]; \n", "    int x[-1][-1][2]; \n",
2245 										   "    int x[-1][-1][-1]; \n" };
2246 
2247 	for (size_t invalid_initializers_index = 0;
2248 		 invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]);
2249 		 invalid_initializers_index++)
2250 	{
2251 		std::string shader_source;
2252 
2253 		shader_source = shader_start;
2254 		shader_source += invalid_initializers[invalid_initializers_index];
2255 
2256 		/* End main */
2257 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2258 
2259 		/* Execute test */
2260 		this->execute_negative_test(tested_shader_type, shader_source);
2261 	} /* for (int invalid_initializers_index = 0; ...) */
2262 }
2263 
2264 /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors4
2265  * array tests, and attempts to compile each test shader, for both
2266  * vertex and fragment shaders.
2267  *
2268  * @tparam API               Tested API descriptor
2269  *
2270  * @param tested_shader_type The type of shader that is being tested
2271  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2272  */
2273 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2274 void ConstructorsAndUnsizedDeclInvalidConstructors4<API>::test_shader_compilation(
2275 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2276 {
2277 	std::string invalid_initializers[] = { "    int x[2][2][a]; \n", "    int x[2][a][2]; \n", "    int x[a][2][2]; \n",
2278 										   "    int x[2][a][a]; \n", "    int x[a][2][a]; \n", "    int x[a][a][2]; \n",
2279 										   "    int x[a][a][a]; \n" };
2280 	std::string non_constant_variable_init = "    uint a = 2u;\n";
2281 
2282 	for (size_t invalid_initializers_index = 0;
2283 		 invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]);
2284 		 invalid_initializers_index++)
2285 	{
2286 		std::string shader_source;
2287 
2288 		shader_source = shader_start;
2289 		shader_source += non_constant_variable_init;
2290 		shader_source += invalid_initializers[invalid_initializers_index];
2291 
2292 		/* End main */
2293 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2294 
2295 		/* Execute test */
2296 		this->execute_negative_test(tested_shader_type, shader_source);
2297 	} /* for (int invalid_initializers_index = 0; ...) */
2298 }
2299 
2300 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructorSizing1
2301  * array tests, and attempts to compile each test shader, for both
2302  * vertex and fragment shaders.
2303  *
2304  * @tparam API               Tested API descriptor
2305  *
2306  * @param tested_shader_type The type of shader that is being tested
2307  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2308  */
2309 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2310 void ConstructorsAndUnsizedDeclConstructorSizing1<API>::test_shader_compilation(
2311 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2312 {
2313 	std::string valid_size_initializers[] = { "[1][1][1][]", "[1][1][][1]", "[1][][1][1]", "[][1][1][1]", "[1][1][][]",
2314 											  "[1][][1][]",  "[][1][1][]",  "[1][][][1]",  "[][1][][1]",  "[][][1][1]",
2315 											  "[1][][][]",   "[][1][][]",   "[][][1][]",   "[][][][1]",   "[][][][]" };
2316 
2317 	for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
2318 	{
2319 		_supported_variable_types_map_const_iterator var_iterator =
2320 			supported_variable_types_map.find(API::var_types[var_type_index]);
2321 
2322 		if (var_iterator != supported_variable_types_map.end())
2323 		{
2324 			for (size_t valid_size_initializers_index = 0;
2325 				 valid_size_initializers_index < sizeof(valid_size_initializers) / sizeof(valid_size_initializers[0]);
2326 				 valid_size_initializers_index++)
2327 			{
2328 				std::string shader_source;
2329 				std::string variable_constructor =
2330 					"    " + var_iterator->second.type + " x" + valid_size_initializers[valid_size_initializers_index] +
2331 					" = " + var_iterator->second.type + "[1][1][1][1](" + var_iterator->second.type + "[1][1][1](" +
2332 					var_iterator->second.type + "[1][1](" + var_iterator->second.type + "[1](" +
2333 					var_iterator->second.initializer_with_zeroes + "))));\n";
2334 
2335 				shader_source = shader_start;
2336 				shader_source += variable_constructor;
2337 
2338 				/* End main */
2339 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2340 
2341 				/* Execute test */
2342 				EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2343 			} /* for (int valid_size_initializers_index = 0; ...) */
2344 		}	 /* if var_type iterator found */
2345 		else
2346 		{
2347 			TCU_FAIL("Type not found.");
2348 		}
2349 	} /* for (int var_type_index = 0; ...) */
2350 }
2351 
2352 /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructorSizing2
2353  * array tests, and attempts to compile each test shader, for both
2354  * vertex and fragment shaders.
2355  *
2356  * @tparam API               Tested API descriptor
2357  *
2358  * @param tested_shader_type The type of shader that is being tested
2359  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2360  */
2361 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2362 void ConstructorsAndUnsizedDeclConstructorSizing2<API>::test_shader_compilation(
2363 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2364 {
2365 	std::string shader_source = shader_start;
2366 
2367 	shader_source += "    float[] a ="
2368 					 "            float[](1.0, 2.0),"
2369 					 "        b[] ="
2370 					 "         float[][]("
2371 					 "             float[](1.0, 2.0),"
2372 					 "             float[](3.0, 4.0)"
2373 					 "         ),"
2374 					 "        c[][] ="
2375 					 "         float[][][]("
2376 					 "             float[][]("
2377 					 "                 float[](1.0),"
2378 					 "                 float[](2.0)"
2379 					 "             )"
2380 					 "         ),"
2381 					 "        d[][][] ="
2382 					 "         float[][][][]("
2383 					 "             float[][][]("
2384 					 "                 float[][]("
2385 					 "                     float[](1.0, 2.0),"
2386 					 "                     float[](3.0, 4.0),"
2387 					 "                     float[](5.0, 6.0)"
2388 					 "                 )"
2389 					 "             ),"
2390 					 "             float[][][]("
2391 					 "                 float[][]("
2392 					 "                     float[](1.0, 2.0),"
2393 					 "                     float[](3.0, 4.0),"
2394 					 "                     float[](5.0, 6.0)"
2395 					 "                 )"
2396 					 "             )"
2397 					 "         ),"
2398 					 "        e[][][][]="
2399 					 "         float[][][][][]("
2400 					 "             float[][][][]("
2401 					 "                 float[][][]("
2402 					 "                     float[][]("
2403 					 "                         float[](1.0),"
2404 					 "                         float[](2.0)"
2405 					 "                     ),"
2406 					 "                     float[][]("
2407 					 "                         float[](1.0),"
2408 					 "                         float[](2.0)"
2409 					 "                     ),"
2410 					 "                     float[][]("
2411 					 "                         float[](1.0),"
2412 					 "                         float[](2.0)"
2413 					 "                     )"
2414 					 "                 ),"
2415 					 "                 float[][][]("
2416 					 "                     float[][]("
2417 					 "                         float[](1.0),"
2418 					 "                         float[](2.0)"
2419 					 "                     ),"
2420 					 "                     float[][]("
2421 					 "                         float[](1.0),"
2422 					 "                         float[](2.0)"
2423 					 "                     ),"
2424 					 "                     float[][]("
2425 					 "                         float[](1.0),"
2426 					 "                         float[](2.0)"
2427 					 "                     )"
2428 					 "                 )"
2429 					 "             )"
2430 					 "         ),"
2431 					 "        f[][][][][]="
2432 					 "         float[][][][][][]("
2433 					 "             float[][][][][]("
2434 					 "                 float[][][][]("
2435 					 "                     float[][][]("
2436 					 "                         float[][]("
2437 					 "                             float[](1.0)"
2438 					 "                         )"
2439 					 "                     )"
2440 					 "                 )"
2441 					 "             )"
2442 					 "         ),"
2443 					 "        g[][][][][][]="
2444 					 "         float[][][][][][][]("
2445 					 "             float[][][][][][]("
2446 					 "                 float[][][][][]("
2447 					 "                     float[][][][]("
2448 					 "                         float[][][]("
2449 					 "                             float[][]("
2450 					 "                                 float[](1.0)"
2451 					 "                             )"
2452 					 "                         )"
2453 					 "                     )"
2454 					 "                 )"
2455 					 "             )"
2456 					 "         ),"
2457 					 "        h[][][][][][][]="
2458 					 "         float[][][][][][][][]("
2459 					 "             float[][][][][][][]("
2460 					 "                 float[][][][][][]("
2461 					 "                     float[][][][][]("
2462 					 "                         float[][][][]("
2463 					 "                             float[][][]("
2464 					 "                                 float[][]("
2465 					 "                                     float[](1.0)"
2466 					 "                                 )"
2467 					 "                             )"
2468 					 "                         )"
2469 					 "                     )"
2470 					 "                 )"
2471 					 "             )"
2472 					 "         );\n";
2473 
2474 	/* End main */
2475 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2476 
2477 	/* Execute test */
2478 	EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2479 }
2480 
2481 /* Constructs a suitable constructor for the specified number of dimensions.
2482  *
2483  * @tparam API            Tested API descriptor
2484  *
2485  * @param var_type        The type of the variable
2486  * @param dimension_index The current recursion level (counts down)
2487  * @param init_string     The initialisation string
2488  */
2489 template <class API>
recursively_initialise(std::string var_type,size_t dimension_index,std::string init_string)2490 std::string ConstructorsAndUnsizedDeclStructConstructors<API>::recursively_initialise(std::string var_type,
2491 																					  size_t	  dimension_index,
2492 																					  std::string init_string)
2493 {
2494 	std::string temp_string;
2495 
2496 	if (dimension_index == 0)
2497 	{
2498 		temp_string = var_type + "(" + init_string + ")";
2499 	}
2500 	else
2501 	{
2502 		std::string prefix = "\n";
2503 
2504 		for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
2505 		{
2506 			prefix += "    ";
2507 		}
2508 
2509 		prefix += this->extend_string(var_type, "[]", dimension_index);
2510 		prefix += "(";
2511 
2512 		for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
2513 		{
2514 			temp_string += prefix;
2515 			temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
2516 			prefix = ", ";
2517 
2518 			if (dimension_index == 1)
2519 			{
2520 				break;
2521 			}
2522 		}
2523 		temp_string += ")";
2524 	}
2525 
2526 	return temp_string;
2527 }
2528 
2529 /* Generates the shader source code for the ConstructorsAndUnsizedDeclStructConstructors
2530  * array tests, and attempts to compile each test shader, for both
2531  * vertex and fragment shaders.
2532  *
2533  * @tparam API               Tested API descriptor
2534  *
2535  * @param tested_shader_type The type of shader that is being tested
2536  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2537  */
2538 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2539 void ConstructorsAndUnsizedDeclStructConstructors<API>::test_shader_compilation(
2540 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2541 {
2542 	std::string example_structure_definition("struct light {\n"
2543 											 "    float intensity;\n"
2544 											 "    int position;\n"
2545 											 "};\n");
2546 	std::string example_structure_object("    light my_light_variable");
2547 
2548 	for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2549 	{
2550 		std::string base_variable_string = this->extend_string(example_structure_object, "[]", max_dimension_index);
2551 		base_variable_string += " = ";
2552 		base_variable_string += recursively_initialise("light", max_dimension_index, "1.0, 2");
2553 		base_variable_string += ";\n\n";
2554 
2555 		std::string shader_source = example_structure_definition + shader_start + base_variable_string;
2556 
2557 		/* End main */
2558 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2559 
2560 		/* Execute test */
2561 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2562 	} /* for (int max_dimension_index = 2; ...) */
2563 }
2564 
2565 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays1
2566  * array tests, and attempts to compile each test shader, for both
2567  * vertex and fragment shaders.
2568  *
2569  * @tparam API               Tested API descriptor
2570  *
2571  * @param tested_shader_type The type of shader that is being tested
2572  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2573  */
2574 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2575 void ConstructorsAndUnsizedDeclUnsizedArrays1<API>::test_shader_compilation(
2576 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2577 {
2578 	std::string base_variable_string;
2579 
2580 	for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2581 	{
2582 		base_variable_string = this->extend_string("    int x", "[]", max_dimension_index);
2583 		base_variable_string += ";\n\n";
2584 
2585 		std::string shader_source = shader_start + base_variable_string;
2586 
2587 		/* End main */
2588 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2589 
2590 		/* Execute test */
2591 		this->execute_negative_test(tested_shader_type, shader_source);
2592 	} /* for (int max_dimension_index = 2; ...) */
2593 }
2594 
2595 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays2
2596  * array tests, and attempts to compile each test shader, for both
2597  * vertex and fragment shaders.
2598  *
2599  * @tparam API               Tested API descriptor
2600  *
2601  * @param tested_shader_type The type of shader that is being tested
2602  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2603  */
2604 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2605 void ConstructorsAndUnsizedDeclUnsizedArrays2<API>::test_shader_compilation(
2606 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2607 {
2608 	std::string input[] = { "    float [] x = float[](1), y;\n\n" };
2609 
2610 	for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
2611 	{
2612 		std::string shader_source;
2613 
2614 		shader_source += shader_start;
2615 		shader_source += input[string_index];
2616 
2617 		/* End main */
2618 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2619 
2620 		/* Execute test */
2621 		EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION, tested_shader_type, shader_source);
2622 	} /* for (int string_index = 0; ...) */
2623 }
2624 
2625 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays3
2626  * array tests, and attempts to compile each test shader, for both
2627  * vertex and fragment shaders.
2628  *
2629  * @tparam API               Tested API descriptor
2630  *
2631  * @param tested_shader_type The type of shader that is being tested
2632  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2633  */
2634 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2635 void ConstructorsAndUnsizedDeclUnsizedArrays3<API>::test_shader_compilation(
2636 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2637 {
2638 	std::string base_variable_string("    float[][] x = mat4(0);\n\n");
2639 
2640 	std::string shader_source = shader_start + base_variable_string;
2641 
2642 	/* End main */
2643 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2644 
2645 	/* Execute test */
2646 	this->execute_negative_test(tested_shader_type, shader_source);
2647 }
2648 
2649 /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays4
2650  * array tests, and attempts to compile each test shader, for both
2651  * vertex and fragment shaders.
2652  *
2653  * @tparam API               Tested API descriptor
2654  *
2655  * @param tested_shader_type The type of shader that is being tested
2656  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2657  */
2658 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2659 void ConstructorsAndUnsizedDeclUnsizedArrays4<API>::test_shader_compilation(
2660 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2661 {
2662 	std::string example_struct("struct light {\n"
2663 							   "    float[][] intensity;\n"
2664 							   "    int       position;\n"
2665 							   "} myLight;\n\n");
2666 
2667 	std::string shader_source = example_struct + shader_start;
2668 
2669 	/* End main */
2670 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2671 
2672 	/* Execute test */
2673 	this->execute_negative_test(tested_shader_type, shader_source);
2674 }
2675 
2676 /* Constructs a suitable constructor for the specified number of dimensions.
2677  *
2678  * @tparam API            Tested API descriptor
2679  *
2680  * @param dimension_index The current recursion level (counts down)
2681  * @param init_string     The initialisation string
2682  */
2683 template <class API>
recursively_initialise(std::string var_type,size_t dimension_index,std::string init_string)2684 std::string ExpressionsAssignment1<API>::recursively_initialise(std::string var_type, size_t dimension_index,
2685 																std::string init_string)
2686 {
2687 	std::string temp_string;
2688 
2689 	if (dimension_index == 0)
2690 	{
2691 		temp_string = init_string;
2692 	}
2693 	else
2694 	{
2695 		std::string prefix = "\n";
2696 
2697 		for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
2698 		{
2699 			prefix += "    ";
2700 		}
2701 
2702 		prefix += this->extend_string(var_type, "[]", dimension_index);
2703 		prefix += "(";
2704 		for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
2705 		{
2706 			temp_string += prefix;
2707 			temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
2708 			prefix = ", ";
2709 			if (dimension_index == 1)
2710 			{
2711 				break;
2712 			}
2713 		}
2714 		temp_string += ")";
2715 	}
2716 
2717 	return temp_string;
2718 }
2719 
2720 /* Generates the shader source code for the ExpressionsAssignment1
2721  * array tests, and attempts to compile each test shader, for both
2722  * vertex and fragment shaders.
2723  *
2724  * @tparam API               Tested API descriptor
2725  *
2726  * @param tested_shader_type The type of shader that is being tested
2727  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2728  */
2729 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2730 void ExpressionsAssignment1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
2731 {
2732 	for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
2733 	{
2734 		std::string prefix = "(";
2735 		std::string base_variable_string;
2736 
2737 		base_variable_string += this->extend_string("    float x", "[2]", max_dimension_index);
2738 		base_variable_string += " = ";
2739 		base_variable_string += recursively_initialise("float", max_dimension_index, "4.0, 6.0");
2740 		base_variable_string += ";\n";
2741 		base_variable_string += this->extend_string("    float y", "[2]", max_dimension_index);
2742 		base_variable_string += " = ";
2743 		base_variable_string += recursively_initialise("float", max_dimension_index, "1.0, 2.0");
2744 		base_variable_string += ";\n\n";
2745 
2746 		std::string shader_source = shader_start + base_variable_string;
2747 
2748 		shader_source += "    x = y;\n";
2749 
2750 		/* End main */
2751 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2752 
2753 		/* Execute test */
2754 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2755 	} /* for (int max_dimension_index = 2; ...) */
2756 }
2757 
2758 /* Generates the shader source code for the ExpressionsAssignment2
2759  * array tests, and attempts to compile each test shader, for both
2760  * vertex and fragment shaders.
2761  *
2762  * @tparam API               Tested API descriptor
2763  *
2764  * @param tested_shader_type The type of shader that is being tested
2765  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2766  */
2767 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2768 void ExpressionsAssignment2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
2769 {
2770 	std::string shader_body("    float a[2] = float[](1.0, 2.0);\n"
2771 							"    float b[2][2] = float[][](float[](1.0, 2.0), float[](1.0, 2.0));\n"
2772 							"    float c[2][2][2] = float[][][]("
2773 							"float[][](float[](1.0, 2.0), float[](1.0, 2.0)),"
2774 							"float[][](float[](1.0, 2.0), float[](1.0, 2.0)));\n"
2775 							"    float d[2][2][2][2] = float[][][][]("
2776 							"float[][][]("
2777 							"float[][](float[](1.0, 2.0), float[](1.0, 2.0)), "
2778 							"float[][](float[](1.0, 2.0), float[](1.0, 2.0))),"
2779 							"float[][][]("
2780 							"float[][](float[](1.0, 2.0), float[](1.0, 2.0)), "
2781 							"float[][](float[](1.0, 2.0), float[](1.0, 2.0))));\n\n");
2782 
2783 	std::string variable_basenames[] = { "a", "b", "c", "d" };
2784 	int			number_of_elements   = sizeof(variable_basenames) / sizeof(variable_basenames[0]);
2785 
2786 	for (int variable_index = 0; variable_index < number_of_elements; variable_index++)
2787 	{
2788 		for (int value_index = variable_index; value_index < number_of_elements; value_index++)
2789 		{
2790 			std::string shader_source = shader_start + shader_body;
2791 
2792 			/* Avoid the situation when a variable is assign to itself. */
2793 			if (variable_index != value_index)
2794 			{
2795 				shader_source += "    " + variable_basenames[variable_index] + " = " + variable_basenames[value_index];
2796 				shader_source += ";\n";
2797 
2798 				/* End main */
2799 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2800 
2801 				/* Execute test */
2802 				this->execute_negative_test(tested_shader_type, shader_source);
2803 			} /* if(variable_index != value_index) */
2804 		}	 /* for (int value_index = variable_index; ...) */
2805 	}		  /* for (int variable_index = 0; ...) */
2806 }
2807 
2808 /* Generates the shader source code for the ExpressionsAssignment3
2809  * array tests, and attempts to compile each test shader, for both
2810  * vertex and fragment shaders.
2811  *
2812  * @tparam API               Tested API descriptor
2813  *
2814  * @param tested_shader_type The type of shader that is being tested
2815  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2816  */
2817 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2818 void ExpressionsAssignment3<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
2819 {
2820 	std::string prefix, base_variable_string;
2821 
2822 	const int test_array_dimensions = 4;
2823 
2824 	prefix = this->extend_string("    float a", "[1]", 4);
2825 	prefix += " = float[][][][](\n"
2826 			  "       float[][][](\n"
2827 			  "           float[][](\n"
2828 			  "               float[](1.0))));\n";
2829 
2830 	prefix += "    float b";
2831 
2832 	for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
2833 	{
2834 		base_variable_string = prefix;
2835 
2836 		for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
2837 		{
2838 			if (permutation & (1 << sub_script_index))
2839 			{
2840 				base_variable_string += "[1]";
2841 			}
2842 			else
2843 			{
2844 				base_variable_string += "[2]";
2845 			}
2846 		}
2847 
2848 		base_variable_string += ";\n\n";
2849 
2850 		if (permutation != (1 << test_array_dimensions) - 1)
2851 		{
2852 			std::string shader_source = shader_start + base_variable_string;
2853 
2854 			shader_source += "    b = a;\n";
2855 
2856 			/* End main */
2857 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2858 
2859 			/* Execute test */
2860 			this->execute_negative_test(tested_shader_type, shader_source);
2861 		} /* if (permutation != (1 << test_array_dimensions) - 1) */
2862 	}	 /* for (int permutation = 0; ...) */
2863 }
2864 
2865 /* Generates the shader source code for the ExpressionsTypeRestrictions1
2866  * array tests, and attempts to compile each test shader, for both
2867  * vertex and fragment shaders.
2868  *
2869  * @tparam API               Tested API descriptor
2870  *
2871  * @param tested_shader_type The type of shader that is being tested
2872  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2873  */
2874 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2875 void ExpressionsTypeRestrictions1<API>::test_shader_compilation(
2876 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2877 {
2878 	int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
2879 
2880 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2881 	{
2882 		_supported_variable_types_map_const_iterator var_iterator =
2883 			supported_variable_types_map.find(opaque_var_types[var_type_index]);
2884 
2885 		if (var_iterator != supported_variable_types_map.end())
2886 		{
2887 			std::string shader_source =
2888 				"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " var1[2][2];\n"
2889 																								"uniform " +
2890 				var_iterator->second.precision + " " + var_iterator->second.type + " var2[2][2];\n\n";
2891 			shader_source += shader_start;
2892 
2893 			shader_source += "    var1 = var2;\n";
2894 
2895 			/* End main */
2896 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2897 
2898 			/* Execute test */
2899 			this->execute_negative_test(tested_shader_type, shader_source);
2900 		} /* if var_type iterator found */
2901 		else
2902 		{
2903 			TCU_FAIL("Type not found.");
2904 		}
2905 	} /* for (int var_type_index = 0; ...) */
2906 }
2907 
2908 /* Generates the shader source code for the ExpressionsTypeRestrictions2
2909  * array tests, and attempts to compile each test shader, for both
2910  * vertex and fragment shaders.
2911  *
2912  * @tparam API               Tested API descriptor
2913  *
2914  * @param tested_shader_type The type of shader that is being tested
2915  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2916  */
2917 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2918 void ExpressionsTypeRestrictions2<API>::test_shader_compilation(
2919 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2920 {
2921 	int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
2922 
2923 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
2924 	{
2925 		_supported_variable_types_map_const_iterator var_iterator =
2926 			supported_variable_types_map.find(opaque_var_types[var_type_index]);
2927 
2928 		if (var_iterator != supported_variable_types_map.end())
2929 		{
2930 			std::string shader_source =
2931 				"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " sampler1;\n"
2932 																								"uniform " +
2933 				var_iterator->second.precision + " " + var_iterator->second.type + " sampler2;\n"
2934 																				   "uniform " +
2935 				var_iterator->second.precision + " " + var_iterator->second.type + " sampler3;\n"
2936 																				   "uniform " +
2937 				var_iterator->second.precision + " " + var_iterator->second.type + " sampler4;\n"
2938 																				   "struct light1 {\n"
2939 																				   "    " +
2940 				var_iterator->second.type + " var1[2][2];\n"
2941 											"};\n\n";
2942 			shader_source += shader_start;
2943 
2944 			shader_source +=
2945 				("    light1 x = light1(" + var_iterator->second.type + "[][](" + var_iterator->second.type +
2946 				 "[](sampler1, sampler2), " + var_iterator->second.type + "[](sampler3, sampler4)));\n");
2947 			shader_source += "    light1 y = x;\n\n";
2948 
2949 			/* End main */
2950 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2951 
2952 			/* Execute test */
2953 			this->execute_negative_test(tested_shader_type, shader_source);
2954 		} /* if var_type iterator found */
2955 		else
2956 		{
2957 			TCU_FAIL("Type not found.");
2958 		}
2959 	} /* for (int var_type_index = 0; ...) */
2960 }
2961 
2962 /* Generates the shader source code for the ExpressionsIndexingScalar1
2963  * array tests, and attempts to compile each test shader, for both
2964  * vertex and fragment shaders.
2965  *
2966  * @tparam API               Tested API descriptor
2967  *
2968  * @param tested_shader_type The type of shader that is being tested
2969  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
2970  */
2971 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)2972 void ExpressionsIndexingScalar1<API>::test_shader_compilation(
2973 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
2974 {
2975 	for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
2976 	{
2977 		_supported_variable_types_map_const_iterator var_iterator =
2978 			supported_variable_types_map.find(API::var_types[var_type_index]);
2979 
2980 		if (var_iterator != supported_variable_types_map.end())
2981 		{
2982 			std::string shader_source = shader_start + "    " + var_iterator->second.type + " x[1][2][3][4];\n\n";
2983 
2984 			shader_source += "    for (uint i = 0u; i < 2u; i++) {\n";
2985 			shader_source += "        for (uint j = 0u; j < 3u; j++) {\n";
2986 			shader_source += "            for (uint k = 0u; k < 4u; k++) {\n";
2987 			shader_source += "                x[0][i][j][k] = " + var_iterator->second.initializer_with_ones + ";\n";
2988 			shader_source += "            }\n";
2989 			shader_source += "        }\n";
2990 			shader_source += "    }\n";
2991 
2992 			/* End main */
2993 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
2994 
2995 			/* Execute test */
2996 			EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
2997 		} /* if var_type iterator found */
2998 		else
2999 		{
3000 			TCU_FAIL("Type not found.");
3001 		}
3002 	}
3003 }
3004 
3005 /* Generates the shader source code for the ExpressionsIndexingScalar2
3006  * array tests, and attempts to compile each test shader, for both
3007  * vertex and fragment shaders.
3008  *
3009  * @tparam API               Tested API descriptor
3010  *
3011  * @param tested_shader_type The type of shader that is being tested
3012  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3013  */
3014 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3015 void ExpressionsIndexingScalar2<API>::test_shader_compilation(
3016 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3017 {
3018 	std::string base_shader_string, shader_source;
3019 
3020 	// This test tests arrays with 4 dimensions, e.g. x[1][1][1][1]
3021 	const int test_array_dimensions = 4;
3022 
3023 	base_shader_string = "float a[1][2][3][4];\n";
3024 	base_shader_string += "float b = 2.0;\n\n";
3025 	base_shader_string += shader_start;
3026 
3027 	// There are 16 permutations, so loop 4x4 times.
3028 	for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
3029 	{
3030 		shader_source = base_shader_string + "    a"; // a var called 'a'
3031 
3032 		for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
3033 		{
3034 			/* If any bit is set for a particular number then add
3035 			 * a valid array sub_script at that place, otherwise
3036 			 * add an invalid array sub_script. */
3037 			if (permutation & (1 << sub_script_index))
3038 			{
3039 				shader_source += "[0]";
3040 			}
3041 			else
3042 			{
3043 				shader_source += "[-1]";
3044 			}
3045 		}
3046 
3047 		shader_source += " = b;\n";
3048 
3049 		if (permutation != (1 << test_array_dimensions) - 1)
3050 		{
3051 			/* End main */
3052 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3053 
3054 			/* Execute test */
3055 			this->execute_negative_test(tested_shader_type, shader_source);
3056 		} /* if (permutation != (1 << test_array_dimensions) - 1) */
3057 	}	 /* for (int permutation = 0; ...) */
3058 }
3059 
3060 /* Generates the shader source code for the ExpressionsIndexingScalar3
3061  * array tests, and attempts to compile each test shader, for both
3062  * vertex and fragment shaders.
3063  *
3064  * @tparam API               Tested API descriptor
3065  *
3066  * @param tested_shader_type The type of shader that is being tested
3067  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3068  */
3069 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3070 void ExpressionsIndexingScalar3<API>::test_shader_compilation(
3071 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3072 {
3073 	std::string base_shader_string;
3074 	std::string shader_source;
3075 	const int   test_array_dimensions = 4;
3076 
3077 	base_shader_string = "float a[1][2][3][4];\n";
3078 	base_shader_string += "float b = 2.0;\n\n";
3079 	base_shader_string += shader_start;
3080 
3081 	for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
3082 	{
3083 		shader_source = base_shader_string + "    a";
3084 
3085 		for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
3086 		{
3087 			if (permutation & (1 << sub_script_index))
3088 			{
3089 				shader_source += "[0]";
3090 			}
3091 			else
3092 			{
3093 				shader_source += "[4]";
3094 			}
3095 		}
3096 
3097 		shader_source += " = b;\n";
3098 
3099 		if (permutation != (1 << test_array_dimensions) - 1)
3100 		{
3101 			/* End main */
3102 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3103 
3104 			/* Execute test */
3105 			this->execute_negative_test(tested_shader_type, shader_source);
3106 		} /* if (permutation != (1 << test_array_dimensions) - 1) */
3107 	}	 /* for (int permutation = 0; ...) */
3108 }
3109 
3110 /* Generates the shader source code for the ExpressionsIndexingScalar4
3111  * array tests, and attempts to compile each test shader, for both
3112  * vertex and fragment shaders.
3113  *
3114  * @tparam API               Tested API descriptor
3115  *
3116  * @param tested_shader_type The type of shader that is being tested
3117  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3118  */
3119 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3120 void ExpressionsIndexingScalar4<API>::test_shader_compilation(
3121 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3122 {
3123 	std::string base_shader_string;
3124 	std::string shader_source;
3125 
3126 	const int test_array_dimensions = 4;
3127 
3128 	base_shader_string = "float a[1][2][3][4];\n";
3129 	base_shader_string += "float b = 2.0;\n\n";
3130 	base_shader_string += shader_start;
3131 
3132 	for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++)
3133 	{
3134 		shader_source = base_shader_string + "    a";
3135 
3136 		for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--)
3137 		{
3138 			if (permutation & (1 << sub_script_index))
3139 			{
3140 				shader_source += "[0]";
3141 			}
3142 			else
3143 			{
3144 				shader_source += "[]";
3145 			}
3146 		}
3147 
3148 		shader_source += " = b;\n";
3149 
3150 		if (permutation != (1 << test_array_dimensions) - 1)
3151 		{
3152 			/* End main */
3153 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3154 
3155 			/* Execute test */
3156 			this->execute_negative_test(tested_shader_type, shader_source);
3157 		} /* if (permutation != (1 << test_array_dimensions) - 1) */
3158 	}	 /* for (int permutation = 0; ...) */
3159 }
3160 
3161 /* Generates the shader source code for the ExpressionsIndexingArray1
3162  * array tests, and attempts to compile each test shader, for both
3163  * vertex and fragment shaders.
3164  *
3165  * @tparam API               Tested API descriptor
3166  *
3167  * @param tested_shader_type The type of shader that is being tested
3168  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3169  */
3170 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3171 void ExpressionsIndexingArray1<API>::test_shader_compilation(
3172 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3173 {
3174 	std::string shader_source;
3175 	std::string variable_declaration = "float x[1][1][1][1][1][1][1][1];\n\n";
3176 
3177 	std::string variable_initializations[] = {
3178 		"x[0]                      = float[1][1][1][1][1][1][1]("
3179 		"float[1][1][1][1][1][1](float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0)))))));"
3180 		"\n",
3181 		"x[0][0]                   = "
3182 		"float[1][1][1][1][1][1](float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0))))));"
3183 		"\n",
3184 		"x[0][0][0]                = "
3185 		"float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0)))));\n",
3186 		"x[0][0][0][0]             = float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0))));\n",
3187 		"x[0][0][0][0][0]          = float[1][1][1](float[1][1](float[1](1.0)));\n",
3188 		"x[0][0][0][0][0][0]       = float[1][1](float[1](1.0));\n", "x[0][0][0][0][0][0][0]    = float[1](1.0);\n",
3189 		"x[0][0][0][0][0][0][0][0] = 1.0;\n"
3190 	};
3191 
3192 	for (size_t string_index = 0; string_index < sizeof(variable_initializations) / sizeof(variable_initializations[0]);
3193 		 string_index++)
3194 	{
3195 		shader_source = variable_declaration + shader_start;
3196 		shader_source += "    " + variable_initializations[string_index];
3197 
3198 		/* End main */
3199 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3200 
3201 		/* Execute test */
3202 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3203 	} /* for (int string_index = 0; ...) */
3204 }
3205 
3206 /* Constructs a suitable constructor for the specified number of dimensions.
3207  *
3208  * @tparam API            Tested API descriptor
3209  *
3210  * @param dimension_index The current recursion level (counts down)
3211  * @param init_string     The initialisation string
3212  */
3213 template <class API>
recursively_initialise(std::string var_type,size_t dimension_index,std::string init_string)3214 std::string ExpressionsIndexingArray2<API>::recursively_initialise(std::string var_type, size_t dimension_index,
3215 																   std::string init_string)
3216 {
3217 	std::string temp_string;
3218 
3219 	if (dimension_index == 0)
3220 	{
3221 		temp_string = init_string;
3222 	}
3223 	else
3224 	{
3225 		std::string prefix = "\n";
3226 
3227 		for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++)
3228 		{
3229 			prefix += "    ";
3230 		}
3231 
3232 		prefix += this->extend_string(var_type, "[]", dimension_index);
3233 		prefix += "(";
3234 		for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++)
3235 		{
3236 			temp_string += prefix;
3237 			temp_string += recursively_initialise(var_type, dimension_index - 1, init_string);
3238 			prefix = ", ";
3239 			if (dimension_index == 1)
3240 			{
3241 				break;
3242 			}
3243 		}
3244 		temp_string += ")";
3245 	}
3246 
3247 	return temp_string;
3248 }
3249 
3250 /* Generates the shader source code for the ExpressionsIndexingArray2
3251  * array tests, and attempts to compile each test shader, for both
3252  * vertex and fragment shaders.
3253  *
3254  * @tparam API               Tested API descriptor
3255  *
3256  * @param tested_shader_type The type of shader that is being tested
3257  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3258  */
3259 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3260 void ExpressionsIndexingArray2<API>::test_shader_compilation(
3261 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3262 {
3263 	std::string variable_initialiser = "    float[](float[](float(float(float(float(float(float(1.0))))))));\n";
3264 
3265 	std::string x_variable_initializaton =
3266 		"    float x[2][2][2][2][2][2][2][1] = " + recursively_initialise("float", API::MAX_ARRAY_DIMENSIONS, "1.0") +
3267 		";\n";
3268 	std::string y_variable_initializaton =
3269 		"    float y[2][2][2][2][2][2][2][1] = " + recursively_initialise("float", API::MAX_ARRAY_DIMENSIONS, "1.0") +
3270 		";\n";
3271 
3272 	std::string shader_code_common_part = shader_start + x_variable_initializaton + y_variable_initializaton;
3273 
3274 	for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++)
3275 	{
3276 		std::string iteration_specific_shader_code_part;
3277 
3278 		iteration_specific_shader_code_part += this->extend_string("    x", "[0]", max_dimension_index);
3279 		iteration_specific_shader_code_part += " = ";
3280 		iteration_specific_shader_code_part += this->extend_string("y", "[0]", max_dimension_index);
3281 		iteration_specific_shader_code_part += ";\n";
3282 
3283 		std::string shader_source = shader_code_common_part + iteration_specific_shader_code_part;
3284 
3285 		/* End main */
3286 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3287 
3288 		/* Execute test */
3289 		EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3290 	}
3291 }
3292 
3293 /* Generates the shader source code for the ExpressionsIndexingArray3
3294  * array tests, and attempts to compile each test shader, for both
3295  * vertex and fragment shaders.
3296  *
3297  * @tparam API               Tested API descriptor
3298  *
3299  * @param tested_shader_type The type of shader that is being tested
3300  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3301  */
3302 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3303 void ExpressionsIndexingArray3<API>::test_shader_compilation(
3304 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3305 {
3306 	std::string input[] = { "    x[ivec2(0)] = 1.0;\n\n", "    x[ivec3(0)] = 1.0;\n\n", "    x[ivec4(0)] = 1.0;\n\n" };
3307 
3308 	for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
3309 	{
3310 		std::string shader_source = shader_start + this->extend_string("    float x", "[2]", (int)string_index + 2) +
3311 									";\n\n" + input[string_index];
3312 
3313 		/* End main */
3314 		DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3315 
3316 		/* Execute test */
3317 		this->execute_negative_test(tested_shader_type, shader_source);
3318 	} /* for (int string_index = 0; ...) */
3319 }
3320 
3321 /* Generates the shader source code for the ExpressionsDynamicIndexing1
3322  * array tests, and attempts to compile each test shader, for both
3323  * vertex and fragment shaders.
3324  *
3325  * @tparam API               Tested API descriptor
3326  *
3327  * @param tested_shader_type The type of shader that is being tested
3328  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3329  */
3330 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3331 void ExpressionsDynamicIndexing1<API>::test_shader_compilation(
3332 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3333 {
3334 	std::string expression_type_declarations = "uniform int a;\n"
3335 											   "const int b = 0;\n"
3336 											   "int c = 0;\n"
3337 											   "float x[2][2];\n";
3338 
3339 	std::string expressions[] = { "a", "b", "c", "0 + 1" };
3340 	std::string shader_source;
3341 
3342 	for (size_t write_index = 0; write_index < sizeof(expressions) / sizeof(expressions[0]); write_index++)
3343 	{
3344 		for (size_t read_index = 0; read_index < sizeof(expressions) / sizeof(expressions[0]); read_index++)
3345 		{
3346 			shader_source = expression_type_declarations;
3347 			shader_source += shader_start;
3348 			shader_source += "    x[";
3349 			shader_source += expressions[write_index];
3350 			shader_source += "][";
3351 			shader_source += expressions[read_index];
3352 			shader_source += "] = 1.0;\n\n";
3353 
3354 			/* End main */
3355 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3356 
3357 			/* Execute test */
3358 			EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3359 		} /* for (int read_index = 0; ...) */
3360 	}	 /* for (int write_index = 0; ...) */
3361 }
3362 
3363 /* Generates the shader source code for the ExpressionsDynamicIndexing2
3364  * array tests, and attempts to compile each test shader, for both
3365  * vertex and fragment shaders.
3366  *
3367  * @tparam API               Tested API descriptor
3368  *
3369  * @param tested_shader_type The type of shader that is being tested
3370  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3371  */
3372 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3373 void ExpressionsDynamicIndexing2<API>::test_shader_compilation(
3374 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
3375 {
3376 	int				  num_var_types				  = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]);
3377 	const std::string invalid_size_declarations[] = { "[0][0][0][y]", "[0][0][y][0]", "[0][y][0][0]", "[y][0][0][0]",
3378 													  "[0][0][y][y]", "[0][y][0][y]", "[y][0][0][y]", "[0][y][y][0]",
3379 													  "[y][0][y][0]", "[y][y][0][0]", "[0][y][y][y]", "[y][0][y][y]",
3380 													  "[y][y][0][y]", "[y][y][y][0]", "[y][y][y][y]" };
3381 
3382 	bool dynamic_indexing_supported = false;
3383 	if (glu::contextSupports(this->context_id.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
3384 		glu::contextSupports(this->context_id.getRenderContext().getType(), glu::ApiType::core(4, 0)) ||
3385 		this->context_id.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"))
3386 	{
3387 		dynamic_indexing_supported = true;
3388 	}
3389 
3390 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
3391 	{
3392 		_supported_variable_types_map_const_iterator var_iterator =
3393 			supported_variable_types_map.find(opaque_var_types[var_type_index]);
3394 
3395 		if (var_iterator != supported_variable_types_map.end())
3396 		{
3397 			int num_invalid_size_declarations =
3398 				sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
3399 
3400 			for (int invalid_size_index = 0; invalid_size_index < num_invalid_size_declarations; invalid_size_index++)
3401 			{
3402 				std::string shader_source = "int y = 1;\n";
3403 
3404 				shader_source += "uniform " + var_iterator->second.precision + " " + var_iterator->second.type +
3405 								 " x[2][2][2][2];\n\n";
3406 				shader_source += "void main()\n";
3407 				shader_source += "{\n";
3408 				shader_source += ("    " + var_iterator->second.type_of_result_of_texture_function +
3409 								  " color = texture(x" + invalid_size_declarations[invalid_size_index] + ", " +
3410 								  var_iterator->second.coord_param_for_texture_function + ");\n");
3411 
3412 				/* End main */
3413 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3414 
3415 				if (dynamic_indexing_supported)
3416 				{
3417 					EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, true);
3418 				}
3419 				else
3420 				{
3421 					this->execute_negative_test(tested_shader_type, shader_source);
3422 				}
3423 			} /* for (int invalid_size_index = 0; ...) */
3424 		}	 /* if var_type iterator found */
3425 		else
3426 		{
3427 			TCU_FAIL("Type not found.");
3428 		}
3429 	} /* for (int var_type_index = 0; ...) */
3430 }
3431 
3432 /* Generates the shader source code for the ExpressionsEquality1
3433  * array tests, and attempts to compile each test shader, for both
3434  * vertex and fragment shaders.
3435  *
3436  * @tparam API               Tested API descriptor
3437  *
3438  * @param tested_shader_type The type of shader that is being tested
3439  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3440  */
3441 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3442 void ExpressionsEquality1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
3443 {
3444 	int num_var_types = API::n_var_types;
3445 
3446 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
3447 	{
3448 		_supported_variable_types_map_const_iterator var_iterator =
3449 			supported_variable_types_map.find(API::var_types[var_type_index]);
3450 
3451 		if (var_iterator != supported_variable_types_map.end())
3452 		{
3453 			std::string shader_source = shader_start;
3454 
3455 			shader_source += "    ";
3456 			shader_source += var_iterator->second.type;
3457 			shader_source += "[][] x = ";
3458 			shader_source += var_iterator->second.type;
3459 			shader_source += "[][](";
3460 			shader_source += var_iterator->second.type;
3461 			shader_source += "[](";
3462 			shader_source += var_iterator->second.initializer_with_zeroes;
3463 			shader_source += ",";
3464 			shader_source += var_iterator->second.initializer_with_zeroes;
3465 			shader_source += "),";
3466 			shader_source += var_iterator->second.type;
3467 			shader_source += "[](";
3468 			shader_source += var_iterator->second.initializer_with_zeroes;
3469 			shader_source += ",";
3470 			shader_source += var_iterator->second.initializer_with_zeroes;
3471 			shader_source += "));\n";
3472 			shader_source += "    ";
3473 			shader_source += var_iterator->second.type;
3474 			shader_source += "[][] y = ";
3475 			shader_source += var_iterator->second.type;
3476 			shader_source += "[][](";
3477 			shader_source += var_iterator->second.type;
3478 			shader_source += "[](";
3479 			shader_source += var_iterator->second.initializer_with_zeroes;
3480 			shader_source += ",";
3481 			shader_source += var_iterator->second.initializer_with_zeroes;
3482 			shader_source += "),";
3483 			shader_source += var_iterator->second.type;
3484 			shader_source += "[](";
3485 			shader_source += var_iterator->second.initializer_with_zeroes;
3486 			shader_source += ",";
3487 			shader_source += var_iterator->second.initializer_with_zeroes;
3488 			shader_source += "));\n\n";
3489 			shader_source += "    float result = 0.0;\n\n";
3490 			shader_source += "    if (x == y)\n";
3491 			shader_source += "    {\n";
3492 			shader_source += "        result = 1.0;\n";
3493 			shader_source += "    }\n";
3494 			shader_source += "    if (y != x)\n";
3495 			shader_source += "    {\n";
3496 			shader_source += "        result = 2.0;\n";
3497 			shader_source += "    }\n";
3498 
3499 			/* End main */
3500 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
3501 
3502 			/* Execute test */
3503 			EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3504 		} /* if var_type iterator found */
3505 		else
3506 		{
3507 			TCU_FAIL("Type not found.");
3508 		}
3509 	}
3510 }
3511 
3512 /* Generates the shader source code for the ExpressionsEquality2
3513  * array tests, and attempts to compile each test shader, for both
3514  * vertex and fragment shaders.
3515  *
3516  * @tparam API               Tested API descriptor
3517  *
3518  * @param tested_shader_type The type of shader that is being tested
3519  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3520  */
3521 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3522 void ExpressionsEquality2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
3523 {
3524 	int num_var_types = API::n_var_types;
3525 
3526 	for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++)
3527 	{
3528 		_supported_variable_types_map_const_iterator var_iterator =
3529 			supported_variable_types_map.find(API::var_types[var_type_index]);
3530 
3531 		if (var_iterator != supported_variable_types_map.end())
3532 		{
3533 			std::string shader_source = "struct light {\n    float intensity;\n    int position;\n};\n\n";
3534 
3535 			shader_source += shader_start;
3536 			shader_source += "    light[][] x =";
3537 			shader_source += "light";
3538 			shader_source += "[][](";
3539 			shader_source += "light";
3540 			shader_source += "[](light(1.0, 1)),";
3541 			shader_source += "light";
3542 			shader_source += "[](light(2.0, 2)));\n\n";
3543 			shader_source += "    light[][] y =";
3544 			shader_source += "light";
3545 			shader_source += "[][](";
3546 			shader_source += "light";
3547 			shader_source += "[](light(3.0, 3)),";
3548 			shader_source += "light";
3549 			shader_source += "[](light(4.0, 4)));\n\n";
3550 			shader_source += "    float result = 0.0;\n\n";
3551 			shader_source += "    if (x == y)\n";
3552 			shader_source += "    {\n";
3553 			shader_source += "        result = 1.0;\n";
3554 			shader_source += "    }\n";
3555 			shader_source += "    if (y != x)\n";
3556 			shader_source += "    {\n";
3557 			shader_source += "        result = 2.0;\n";
3558 			shader_source += "    }\n";
3559 
3560 			/* Apply stage specific stuff */
3561 			switch (tested_shader_type)
3562 			{
3563 			case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3564 				shader_source += "\n    gl_Position = vec4(0.0,0.0,0.0,1.0);\n";
3565 				break;
3566 			case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3567 				shader_source += "\n    gl_FragDepth = result;\n";
3568 				break;
3569 			case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3570 				break;
3571 			case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3572 				shader_source += emit_quad;
3573 				break;
3574 			case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
3575 				shader_source += set_tesseation;
3576 				break;
3577 			case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3578 				break;
3579 			default:
3580 				TCU_FAIL("Unrecognized shader type.");
3581 				break;
3582 			}
3583 
3584 			/* End main function */
3585 			shader_source += shader_end;
3586 
3587 			/* Execute test */
3588 			EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
3589 		} /* if var_type iterator found */
3590 		else
3591 		{
3592 			TCU_FAIL("Type not found.");
3593 		}
3594 	}
3595 }
3596 
3597 /* Generates the shader source code for the ExpressionsLength1
3598  * array tests, and attempts to compile each test shader, for both
3599  * vertex and fragment shaders.
3600  *
3601  * @tparam API               Tested API descriptor
3602  *
3603  * @param tested_shader_type The type of shader that is being tested
3604  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
3605  */
3606 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)3607 void ExpressionsLength1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
3608 {
3609 	std::string array_declaration	  = "    int x[4][3][2][1];\n\n";
3610 	std::string case_specific_string[] = { "    if (x.length() != 4) {\n"
3611 										   "        result = 0.0f;\n    }\n",
3612 										   "    if (x[0].length() != 3) {\n"
3613 										   "        result = 0.0f;\n    }\n",
3614 										   "    if (x[0][0].length() != 2) {\n"
3615 										   "        result = 0.0f;\n    }\n",
3616 										   "    if (x[0][0][0].length() != 1) {\n"
3617 										   "        result = 0.0f;\n    }\n" };
3618 	const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
3619 
3620 	for (size_t case_specific_string_index = 0;
3621 		 case_specific_string_index < sizeof(case_specific_string) / sizeof(case_specific_string[0]);
3622 		 case_specific_string_index++)
3623 	{
3624 		const std::string& test_snippet = case_specific_string[case_specific_string_index];
3625 
3626 		if (false == test_compute)
3627 		{
3628 			execute_draw_test(tested_shader_type, array_declaration, test_snippet);
3629 		}
3630 		else
3631 		{
3632 			execute_dispatch_test(tested_shader_type, array_declaration, test_snippet);
3633 		}
3634 
3635 		/* Deallocate any resources used. */
3636 		this->delete_objects();
3637 	} /* for (int case_specific_string_index = 0; ...) */
3638 }
3639 
3640 /** Executes test for compute program
3641  *
3642  * @tparam API               Tested API descriptor
3643  *
3644  * @param tested_shader_type The type of shader that is being tested
3645  * @param tested_declaration Declaration used to prepare shader
3646  * @param tested_snippet     Snippet used to prepare shader
3647  **/
3648 template <class API>
execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)3649 void ExpressionsLength1<API>::execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
3650 													const std::string&						   tested_declaration,
3651 													const std::string&						   tested_snippet)
3652 {
3653 	const std::string& compute_shader_source =
3654 		prepare_compute_shader(tested_shader_type, tested_declaration, tested_snippet);
3655 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
3656 
3657 	this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string,
3658 								compute_shader_source, false, false);
3659 
3660 	/* We are now ready to verify whether the returned size is correct. */
3661 	unsigned char buffer[4]				= { 0 };
3662 	glw::GLuint   framebuffer_object_id = 0;
3663 	glw::GLint	location				= -1;
3664 	glw::GLuint   texture_object_id		= 0;
3665 	glw::GLuint   vao_id				= 0;
3666 
3667 	gl.useProgram(this->program_object_id);
3668 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
3669 
3670 	gl.genTextures(1, &texture_object_id);
3671 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
3672 
3673 	gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
3674 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
3675 
3676 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3677 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
3678 
3679 	gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
3680 						GL_WRITE_ONLY, GL_RGBA8);
3681 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed.");
3682 
3683 	location = gl.getUniformLocation(this->program_object_id, "uni_image");
3684 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
3685 
3686 	if (-1 == location)
3687 	{
3688 		TCU_FAIL("Uniform is inactive");
3689 	}
3690 
3691 	gl.uniform1i(location, 0 /* image unit */);
3692 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
3693 
3694 	gl.genVertexArrays(1, &vao_id);
3695 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
3696 
3697 	gl.bindVertexArray(vao_id);
3698 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
3699 
3700 	gl.dispatchCompute(1, 1, 1);
3701 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3702 
3703 	gl.genFramebuffers(1, &framebuffer_object_id);
3704 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
3705 
3706 	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
3707 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
3708 
3709 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
3710 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
3711 
3712 	gl.viewport(0, 0, 1, 1);
3713 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
3714 
3715 	gl.readBuffer(GL_COLOR_ATTACHMENT0);
3716 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
3717 
3718 	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
3719 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
3720 
3721 	if (buffer[0] != 255)
3722 	{
3723 		TCU_FAIL("Invalid array size was returned.");
3724 	}
3725 
3726 	/* Delete generated objects. */
3727 	gl.deleteTextures(1, &texture_object_id);
3728 	gl.deleteFramebuffers(1, &framebuffer_object_id);
3729 	gl.deleteVertexArrays(1, &vao_id);
3730 	GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
3731 }
3732 
3733 /** Executes test for draw program
3734  *
3735  * @tparam API               Tested API descriptor
3736  *
3737  * @param tested_shader_type The type of shader that is being tested
3738  * @param tested_declaration Declaration used to prepare shader
3739  * @param tested_snippet     Snippet used to prepare shader
3740  **/
3741 template <class API>
execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)3742 void ExpressionsLength1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
3743 												const std::string&						   tested_declaration,
3744 												const std::string&						   tested_snippet)
3745 {
3746 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
3747 
3748 	if (API::USE_ALL_SHADER_STAGES)
3749 	{
3750 		const std::string& compute_shader_source = empty_string;
3751 		const std::string& fragment_shader_source =
3752 			this->prepare_fragment_shader(tested_shader_type, tested_declaration, tested_snippet);
3753 		const std::string& geometry_shader_source =
3754 			this->prepare_geometry_shader(tested_shader_type, tested_declaration, tested_snippet);
3755 		const std::string& tess_ctrl_shader_source =
3756 			this->prepare_tess_ctrl_shader(tested_shader_type, tested_declaration, tested_snippet);
3757 		const std::string& tess_eval_shader_source =
3758 			this->prepare_tess_eval_shader(tested_shader_type, tested_declaration, tested_snippet);
3759 		const std::string& vertex_shader_source =
3760 			this->prepare_vertex_shader(tested_shader_type, tested_declaration, tested_snippet);
3761 
3762 		switch (tested_shader_type)
3763 		{
3764 		case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
3765 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3766 			this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
3767 			break;
3768 
3769 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3770 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3771 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
3772 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3773 			this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
3774 										geometry_shader_source, fragment_shader_source, compute_shader_source, false,
3775 										false);
3776 			break;
3777 
3778 		default:
3779 			TCU_FAIL("Invalid enum");
3780 			break;
3781 		}
3782 	}
3783 	else
3784 	{
3785 		const std::string& fragment_shader_source =
3786 			this->prepare_fragment_shader(tested_shader_type, tested_declaration, tested_snippet);
3787 		const std::string& vertex_shader_source =
3788 			this->prepare_vertex_shader(tested_shader_type, tested_declaration, tested_snippet);
3789 
3790 		this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
3791 	}
3792 
3793 	/* We are now ready to verify whether the returned size is correct. */
3794 	unsigned char buffer[4]				= { 0 };
3795 	glw::GLuint   framebuffer_object_id = 0;
3796 	glw::GLuint   texture_object_id		= 0;
3797 	glw::GLuint   vao_id				= 0;
3798 
3799 	gl.useProgram(this->program_object_id);
3800 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
3801 
3802 	gl.genTextures(1, &texture_object_id);
3803 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
3804 
3805 	gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
3806 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
3807 
3808 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3809 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
3810 
3811 	gl.genFramebuffers(1, &framebuffer_object_id);
3812 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
3813 
3814 	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
3815 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
3816 
3817 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
3818 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
3819 
3820 	gl.viewport(0, 0, 1, 1);
3821 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
3822 
3823 	gl.genVertexArrays(1, &vao_id);
3824 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
3825 
3826 	gl.bindVertexArray(vao_id);
3827 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
3828 
3829 	switch (tested_shader_type)
3830 	{
3831 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
3832 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3833 		gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
3834 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3835 		break;
3836 
3837 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
3838 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3839 		/* Tesselation patch set up */
3840 		gl.patchParameteri(GL_PATCH_VERTICES, 1);
3841 		GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
3842 
3843 		gl.drawArrays(GL_PATCHES, 0, 1);
3844 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3845 		break;
3846 
3847 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3848 		gl.drawArrays(GL_POINTS, 0, 1);
3849 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
3850 		break;
3851 
3852 	default:
3853 		TCU_FAIL("Invalid enum");
3854 		break;
3855 	}
3856 
3857 	gl.readBuffer(GL_COLOR_ATTACHMENT0);
3858 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
3859 
3860 	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
3861 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
3862 
3863 	if (buffer[0] != 255)
3864 	{
3865 		TCU_FAIL("Invalid array size was returned.");
3866 	}
3867 
3868 	/* Delete generated objects. */
3869 	gl.deleteTextures(1, &texture_object_id);
3870 	gl.deleteFramebuffers(1, &framebuffer_object_id);
3871 	gl.deleteVertexArrays(1, &vao_id);
3872 	GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
3873 }
3874 
3875 /** Prepare shader
3876  *
3877  * @tparam API               Tested API descriptor
3878  *
3879  * @param tested_shader_type The type of shader that is being tested
3880  * @param tested_declaration Declaration used to prepare shader
3881  * @param tested_snippet     Snippet used to prepare shader
3882  **/
3883 template <class API>
prepare_compute_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)3884 std::string ExpressionsLength1<API>::prepare_compute_shader(
3885 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
3886 	const std::string& tested_snippet)
3887 {
3888 	std::string compute_shader_source;
3889 
3890 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
3891 	{
3892 		compute_shader_source = "writeonly uniform image2D uni_image;\n"
3893 								"\n"
3894 								"void main()\n"
3895 								"{\n"
3896 								"    float result = 1u;\n"
3897 								"\n";
3898 		compute_shader_source += tested_declaration;
3899 		compute_shader_source += tested_snippet;
3900 		compute_shader_source += "\n"
3901 								 "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
3902 								 "}\n"
3903 								 "\n";
3904 	}
3905 
3906 	return compute_shader_source;
3907 }
3908 
3909 /** Prepare shader
3910  *
3911  * @tparam API               Tested API descriptor
3912  *
3913  * @param tested_shader_type The type of shader that is being tested
3914  * @param tested_declaration Declaration used to prepare shader
3915  * @param tested_snippet     Snippet used to prepare shader
3916  **/
3917 template <class API>
prepare_fragment_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)3918 std::string ExpressionsLength1<API>::prepare_fragment_shader(
3919 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
3920 	const std::string& tested_snippet)
3921 {
3922 	std::string fragment_shader_source;
3923 
3924 	switch (tested_shader_type)
3925 	{
3926 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3927 		break;
3928 
3929 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3930 		fragment_shader_source = "out vec4 colour;\n"
3931 								 "\n"
3932 								 "void main()\n"
3933 								 "{\n";
3934 		fragment_shader_source += tested_declaration;
3935 		fragment_shader_source += "    float result = 1.0f;\n";
3936 		fragment_shader_source += tested_snippet;
3937 		fragment_shader_source += "    colour = vec4(result);\n"
3938 								  "}\n\n";
3939 		break;
3940 
3941 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
3942 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
3943 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3944 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3945 		fragment_shader_source = "in float fs_result;\n\n"
3946 								 "out vec4 colour;\n\n"
3947 								 "void main()\n"
3948 								 "{\n"
3949 								 "    colour =  vec4(fs_result);\n"
3950 								 "}\n"
3951 								 "\n";
3952 		break;
3953 
3954 	default:
3955 		TCU_FAIL("Unrecognized shader object type.");
3956 		break;
3957 	}
3958 
3959 	return fragment_shader_source;
3960 }
3961 
3962 /** Prepare shader
3963  *
3964  * @tparam API               Tested API descriptor
3965  *
3966  * @param tested_shader_type The type of shader that is being tested
3967  * @param tested_declaration Declaration used to prepare shader
3968  * @param tested_snippet     Snippet used to prepare shader
3969  **/
3970 template <class API>
prepare_geometry_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)3971 std::string ExpressionsLength1<API>::prepare_geometry_shader(
3972 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
3973 	const std::string& tested_snippet)
3974 {
3975 	std::string geometry_shader_source;
3976 
3977 	switch (tested_shader_type)
3978 	{
3979 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
3980 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
3981 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
3982 		break;
3983 
3984 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
3985 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
3986 		geometry_shader_source = "layout(points)                           in;\n"
3987 								 "layout(triangle_strip, max_vertices = 4) out;\n"
3988 								 "\n"
3989 								 "in  float tes_result[];\n"
3990 								 "out float fs_result;\n"
3991 								 "\n"
3992 								 "void main()\n"
3993 								 "{\n"
3994 								 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
3995 								 "    fs_result    = tes_result[0];\n"
3996 								 "    EmitVertex();\n"
3997 								 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
3998 								 "    fs_result    = tes_result[0];\n"
3999 								 "    EmitVertex();\n"
4000 								 "    gl_Position  = vec4(1, -1, 0, 1);\n"
4001 								 "    fs_result    = tes_result[0];\n"
4002 								 "    EmitVertex();\n"
4003 								 "    gl_Position  = vec4(1, 1, 0, 1);\n"
4004 								 "    fs_result    = tes_result[0];\n"
4005 								 "    EmitVertex();\n"
4006 								 "}\n";
4007 		break;
4008 
4009 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4010 		geometry_shader_source = "layout(points)                           in;\n"
4011 								 "layout(triangle_strip, max_vertices = 4) out;\n"
4012 								 "\n"
4013 								 "out float fs_result;\n"
4014 								 "\n"
4015 								 "void main()\n"
4016 								 "{\n";
4017 		geometry_shader_source += tested_declaration;
4018 		geometry_shader_source += "    float result = 1.0;\n\n";
4019 		geometry_shader_source += tested_snippet;
4020 		geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
4021 								  "    fs_result    = result;\n"
4022 								  "    EmitVertex();\n"
4023 								  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
4024 								  "    fs_result    = result;\n"
4025 								  "    EmitVertex();\n"
4026 								  "    gl_Position  = vec4(1, -1, 0, 1);\n"
4027 								  "    fs_result    = result;\n"
4028 								  "    EmitVertex();\n"
4029 								  "    gl_Position  = vec4(1, 1, 0, 1);\n"
4030 								  "    fs_result    = result;\n"
4031 								  "    EmitVertex();\n"
4032 								  "}\n";
4033 		break;
4034 
4035 	default:
4036 		TCU_FAIL("Unrecognized shader object type.");
4037 		break;
4038 	}
4039 
4040 	return geometry_shader_source;
4041 }
4042 
4043 /** Prepare shader
4044  *
4045  * @tparam API               Tested API descriptor
4046  *
4047  * @param tested_shader_type The type of shader that is being tested
4048  * @param tested_declaration Declaration used to prepare shader
4049  * @param tested_snippet     Snippet used to prepare shader
4050  **/
4051 template <class API>
prepare_tess_ctrl_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)4052 std::string ExpressionsLength1<API>::prepare_tess_ctrl_shader(
4053 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
4054 	const std::string& tested_snippet)
4055 {
4056 	std::string tess_ctrl_shader_source;
4057 
4058 	switch (tested_shader_type)
4059 	{
4060 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4061 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4062 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4063 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4064 		break;
4065 
4066 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4067 		tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
4068 								  "\n"
4069 								  "out float tcs_result[];\n"
4070 								  "\n"
4071 								  "void main()\n"
4072 								  "{\n";
4073 		tess_ctrl_shader_source += tested_declaration;
4074 		tess_ctrl_shader_source += "    float result = 1.0;\n\n";
4075 		tess_ctrl_shader_source += tested_snippet;
4076 		tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
4077 								   "\n"
4078 								   "    gl_TessLevelOuter[0] = 1.0;\n"
4079 								   "    gl_TessLevelOuter[1] = 1.0;\n"
4080 								   "    gl_TessLevelOuter[2] = 1.0;\n"
4081 								   "    gl_TessLevelOuter[3] = 1.0;\n"
4082 								   "    gl_TessLevelInner[0] = 1.0;\n"
4083 								   "    gl_TessLevelInner[1] = 1.0;\n"
4084 								   "}\n";
4085 		break;
4086 
4087 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4088 		tess_ctrl_shader_source = default_tc_shader_source;
4089 		break;
4090 
4091 	default:
4092 		TCU_FAIL("Unrecognized shader object type.");
4093 		break;
4094 	}
4095 
4096 	return tess_ctrl_shader_source;
4097 }
4098 
4099 /** Prepare shader
4100  *
4101  * @tparam API               Tested API descriptor
4102  *
4103  * @param tested_shader_type The type of shader that is being tested
4104  * @param tested_declaration Declaration used to prepare shader
4105  * @param tested_snippet     Snippet used to prepare shader
4106  **/
4107 template <class API>
prepare_tess_eval_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)4108 std::string ExpressionsLength1<API>::prepare_tess_eval_shader(
4109 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
4110 	const std::string& tested_snippet)
4111 {
4112 	std::string tess_eval_shader_source;
4113 
4114 	switch (tested_shader_type)
4115 	{
4116 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4117 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4118 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4119 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4120 		break;
4121 
4122 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4123 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
4124 								  "\n"
4125 								  "in  float tcs_result[];\n"
4126 								  "out float tes_result;\n"
4127 								  "\n"
4128 								  "void main()\n"
4129 								  "{\n"
4130 								  "    tes_result = tcs_result[0];\n"
4131 								  "}\n";
4132 		break;
4133 
4134 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4135 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
4136 								  "\n"
4137 								  "out float tes_result;\n"
4138 								  "\n"
4139 								  "void main()\n"
4140 								  "{\n";
4141 		tess_eval_shader_source += tested_declaration;
4142 		tess_eval_shader_source += "    float result = 1.0;\n\n";
4143 		tess_eval_shader_source += tested_snippet;
4144 		tess_eval_shader_source += "    tes_result = result;\n"
4145 								   "}\n";
4146 		break;
4147 
4148 	default:
4149 		TCU_FAIL("Unrecognized shader object type.");
4150 		break;
4151 	}
4152 
4153 	return tess_eval_shader_source;
4154 }
4155 
4156 /** Prepare shader
4157  *
4158  * @tparam API               Tested API descriptor
4159  *
4160  * @param tested_shader_type The type of shader that is being tested
4161  * @param tested_declaration Declaration used to prepare shader
4162  * @param tested_snippet     Snippet used to prepare shader
4163  **/
4164 template <class API>
prepare_vertex_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & tested_declaration,const std::string & tested_snippet)4165 std::string ExpressionsLength1<API>::prepare_vertex_shader(
4166 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration,
4167 	const std::string& tested_snippet)
4168 {
4169 	std::string vertex_shader_source;
4170 
4171 	switch (tested_shader_type)
4172 	{
4173 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4174 		break;
4175 
4176 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4177 		vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
4178 							   "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
4179 							   "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
4180 							   "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
4181 							   "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
4182 							   "\n"
4183 							   "void main()\n"
4184 							   "{\n"
4185 							   "    gl_Position = vertex_positions[gl_VertexID];"
4186 							   "}\n\n";
4187 		break;
4188 
4189 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4190 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4191 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4192 		vertex_shader_source = default_vertex_shader_source;
4193 		break;
4194 
4195 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4196 		vertex_shader_source = "out float fs_result;\n"
4197 							   "\n"
4198 							   "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
4199 							   "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
4200 							   "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
4201 							   "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
4202 							   "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
4203 							   "\n"
4204 							   "void main()\n"
4205 							   "{\n";
4206 		vertex_shader_source += tested_declaration;
4207 		vertex_shader_source += "    float result = 1.0;\n\n";
4208 		vertex_shader_source += tested_snippet;
4209 		vertex_shader_source += "    gl_Position = vertex_positions[gl_VertexID];\n"
4210 								"    fs_result = result;\n";
4211 		vertex_shader_source += shader_end;
4212 		break;
4213 
4214 	default:
4215 		TCU_FAIL("Unrecognized shader object type.");
4216 		break;
4217 	}
4218 
4219 	return vertex_shader_source;
4220 }
4221 
4222 /* Generates the shader source code for the ExpressionsLength2
4223  * array tests, and attempts to compile each test shader, for both
4224  * vertex and fragment shaders.
4225  *
4226  * @tparam API               Tested API descriptor
4227  *
4228  * @param tested_shader_type The type of shader that is being tested
4229  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4230  */
4231 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)4232 void ExpressionsLength2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4233 {
4234 	std::string array_declaration	  = "    int x[1][2][3][4];\n\n";
4235 	std::string case_specific_string[] = { "    if (x.length() != 1) {\n"
4236 										   "        result = 0.0f;\n    }\n",
4237 										   "    if (x[0].length() != 2) {\n"
4238 										   "        result = 0.0f;\n    }\n",
4239 										   "    if (x[0][0].length() != 3) {\n"
4240 										   "        result = 0.0f;\n    }\n",
4241 										   "    if (x[0][0][0].length() != 4) {\n"
4242 										   "        result = 0.0f;\n    }\n" };
4243 	const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
4244 
4245 	for (size_t case_specific_string_index = 0;
4246 		 case_specific_string_index < sizeof(case_specific_string) / sizeof(case_specific_string[0]);
4247 		 case_specific_string_index++)
4248 	{
4249 		const std::string& test_snippet = case_specific_string[case_specific_string_index];
4250 
4251 		if (false == test_compute)
4252 		{
4253 			this->execute_draw_test(tested_shader_type, array_declaration, test_snippet);
4254 		}
4255 		else
4256 		{
4257 			this->execute_dispatch_test(tested_shader_type, array_declaration, test_snippet);
4258 		}
4259 
4260 		/* Deallocate any resources used. */
4261 		this->delete_objects();
4262 	} /* for (int case_specific_string_index = 0; ...) */
4263 }
4264 
4265 /* Generates the shader source code for the ExpressionsLength3
4266  * array tests, and attempts to compile each test shader, for both
4267  * vertex and fragment shaders.
4268  *
4269  * @tparam API               Tested API descriptor
4270  *
4271  * @param tested_shader_type The type of shader that is being tested
4272  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4273  */
4274 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)4275 void ExpressionsLength3<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4276 {
4277 	std::string array_declaration = "    int x[1][1][1][1];\n\n";
4278 	std::string input[]			  = { "    if (x[].length() != 2) {\n"
4279 							"        result = 0.0f;\n    }\n",
4280 							"    if (x[][].length() != 2)  {\n"
4281 							"        result = 0.0f;\n    }\n",
4282 							"    if (x[][][].length() != 2)  {\n"
4283 							"        result = 0.0f;\n    }\n" };
4284 
4285 	for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++)
4286 	{
4287 		std::string		   shader_source;
4288 		const std::string& test_snippet = input[string_index];
4289 
4290 		switch (tested_shader_type)
4291 		{
4292 		case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4293 			shader_source = this->prepare_vertex_shader(tested_shader_type, array_declaration, test_snippet);
4294 			break;
4295 
4296 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4297 			shader_source = this->prepare_fragment_shader(tested_shader_type, array_declaration, test_snippet);
4298 			break;
4299 
4300 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4301 			shader_source = this->prepare_compute_shader(tested_shader_type, array_declaration, test_snippet);
4302 			break;
4303 
4304 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4305 			shader_source = this->prepare_geometry_shader(tested_shader_type, array_declaration, test_snippet);
4306 			break;
4307 
4308 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4309 			shader_source = this->prepare_tess_ctrl_shader(tested_shader_type, array_declaration, test_snippet);
4310 			break;
4311 
4312 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4313 			shader_source = this->prepare_tess_eval_shader(tested_shader_type, array_declaration, test_snippet);
4314 			break;
4315 
4316 		default:
4317 			TCU_FAIL("Unrecognized shader type.");
4318 			break;
4319 		} /* switch (tested_shader_type) */
4320 
4321 		this->execute_negative_test(tested_shader_type, shader_source);
4322 	} /* for (int string_index = 0; ...) */
4323 }
4324 
4325 /* Generates the shader source code for the ExpressionsInvalid1
4326  * array tests, and attempts to compile each test shader, for both
4327  * vertex and fragment shaders.
4328  *
4329  * @tparam API               Tested API descriptor
4330  *
4331  * @param tested_shader_type The type of shader that is being tested
4332  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4333  */
4334 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)4335 void ExpressionsInvalid1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4336 {
4337 	std::string shader_variable_declarations =
4338 		"    mat2  y       = mat2(0.0);\n"
4339 		"    float x[2][2] = float[2][2](float[2](4.0, 5.0), float[2](6.0, 7.0));\n\n";
4340 
4341 	std::string shader_source = shader_start + shader_variable_declarations;
4342 
4343 	shader_source += "    y = x;\n";
4344 
4345 	DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
4346 
4347 	this->execute_negative_test(tested_shader_type, shader_source);
4348 }
4349 
4350 /* Generates the shader source code for the ExpressionsInvalid2
4351  * array tests, and attempts to compile each test shader, for both
4352  * vertex and fragment shaders.
4353  *
4354  * @tparam API               Tested API descriptor
4355  *
4356  * @param tested_shader_type The type of shader that is being tested
4357  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4358  */
4359 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)4360 void ExpressionsInvalid2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
4361 {
4362 
4363 	std::string shader_variable_declarations[] = { " x", " y" };
4364 	std::string variable_relation_opeartors[]  = {
4365 		"    float result = 0.0;\n\n    if(x < y)\n    {\n        result = 1.0;\n    }\n\n\n",
4366 		"    float result = 0.0;\n\n    if(x <= y)\n    {\n        result = 1.0;\n    }\n\n\n",
4367 		"    float result = 0.0;\n\n    if(x > y)\n    {\n        result = 1.0;\n    }\n\n\n",
4368 		"    float result = 0.0;\n\n    if(x >= y)\n    {\n        result = 1.0;\n    }\n\n\n"
4369 	};
4370 	std::string valid_relation_opeartors =
4371 		"    float result = 0.0;\n\n    if(x == y)\n    {\n        result = 1.0;\n    }\n\n\n";
4372 
4373 	for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++)
4374 	{
4375 		_supported_variable_types_map_const_iterator var_iterator =
4376 			supported_variable_types_map.find(API::var_types[var_type_index]);
4377 
4378 		if (var_iterator != supported_variable_types_map.end())
4379 		{
4380 			std::string base_variable_string;
4381 
4382 			for (size_t variable_declaration_index = 0;
4383 				 variable_declaration_index <
4384 				 sizeof(shader_variable_declarations) / sizeof(shader_variable_declarations[0]);
4385 				 variable_declaration_index++)
4386 			{
4387 				base_variable_string += var_iterator->second.type;
4388 				base_variable_string += shader_variable_declarations[variable_declaration_index];
4389 
4390 				base_variable_string += "[1][1][1][1][1][1][1][1] = ";
4391 
4392 				for (size_t sub_script_index = 0; sub_script_index < API::MAX_ARRAY_DIMENSIONS; sub_script_index++)
4393 				{
4394 					base_variable_string += this->extend_string(var_iterator->second.type, "[1]",
4395 																API::MAX_ARRAY_DIMENSIONS - sub_script_index);
4396 					base_variable_string += "(";
4397 				}
4398 
4399 				base_variable_string += var_iterator->second.initializer_with_ones;
4400 
4401 				for (size_t sub_script_index = 0; sub_script_index < API::MAX_ARRAY_DIMENSIONS; sub_script_index++)
4402 				{
4403 					base_variable_string += ")";
4404 				}
4405 
4406 				base_variable_string += ";\n";
4407 			} /* for (int variable_declaration_index = 0; ...) */
4408 
4409 			/* Run positive case */
4410 			{
4411 				std::string shader_source;
4412 
4413 				shader_source = base_variable_string + "\n";
4414 				shader_source += shader_start + valid_relation_opeartors;
4415 
4416 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
4417 
4418 				EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
4419 			}
4420 
4421 			/* Run negative cases */
4422 			for (size_t string_index = 0;
4423 				 string_index < sizeof(variable_relation_opeartors) / sizeof(variable_relation_opeartors[0]);
4424 				 string_index++)
4425 			{
4426 				std::string shader_source;
4427 
4428 				shader_source = base_variable_string + "\n";
4429 				shader_source += shader_start + variable_relation_opeartors[string_index];
4430 
4431 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
4432 
4433 				this->execute_negative_test(tested_shader_type, shader_source);
4434 			} /* for (int string_index = 0; ...) */
4435 		}	 /* if var_type iterator found */
4436 		else
4437 		{
4438 			TCU_FAIL("Type not found.");
4439 		}
4440 	} /* for (int var_type_index = 0; ...) */
4441 }
4442 
4443 /* Generates the shader source code for the InteractionFunctionCalls1
4444  * array tests, and attempts to compile each test shader, for both
4445  * vertex and fragment shaders.
4446  *
4447  * @tparam API               Tested API descriptor
4448  *
4449  * @param tested_shader_type The type of shader that is being tested
4450  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
4451  */
4452 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)4453 void InteractionFunctionCalls1<API>::test_shader_compilation(
4454 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
4455 {
4456 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
4457 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
4458 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
4459 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
4460 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
4461 
4462 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
4463 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
4464 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
4465 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
4466 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
4467 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
4468 
4469 	const std::string iteration_loop_end = "                }\n"
4470 										   "            }\n"
4471 										   "        }\n"
4472 										   "    }\n";
4473 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
4474 											 "    {\n"
4475 											 "        for (uint b = 0u; b < 2u; b++)\n"
4476 											 "        {\n"
4477 											 "            for (uint c = 0u; c < 2u; c++)\n"
4478 											 "            {\n"
4479 											 "                for (uint d = 0u; d < 2u; d++)\n"
4480 											 "                {\n";
4481 	const glcts::test_var_type* var_types_set = var_types_set_es;
4482 	size_t						num_var_types = num_var_types_es;
4483 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
4484 
4485 	if (API::USE_DOUBLE)
4486 	{
4487 		var_types_set = var_types_set_gl;
4488 		num_var_types = num_var_types_gl;
4489 	}
4490 
4491 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
4492 	{
4493 		_supported_variable_types_map_const_iterator var_iterator =
4494 			supported_variable_types_map.find(var_types_set[var_type_index]);
4495 
4496 		if (var_iterator != supported_variable_types_map.end())
4497 		{
4498 			std::string iterator_declaration = "    " + var_iterator->second.iterator_type +
4499 											   " iterator = " + var_iterator->second.iterator_initialization + ";\n";
4500 
4501 			std::string function_definition;
4502 			std::string function_use;
4503 			std::string verification;
4504 
4505 			function_definition = "void my_function(out ";
4506 			function_definition += var_iterator->second.type;
4507 			function_definition += " output_array[2][2][2][2]) {\n";
4508 			function_definition += iterator_declaration;
4509 			function_definition += iteration_loop_start;
4510 			function_definition += "                                   output_array[a][b][c][d] = " +
4511 								   var_iterator->second.variable_type_initializer1 + ";\n";
4512 			function_definition +=
4513 				"                                   iterator += " + var_iterator->second.iterator_type + "(1);\n";
4514 			function_definition += iteration_loop_end;
4515 			function_definition += "}";
4516 
4517 			function_use = "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
4518 			function_use += "    my_function(my_array);";
4519 
4520 			verification = iterator_declaration;
4521 			verification += "    float result = 1.0;\n";
4522 			verification += iteration_loop_start;
4523 			verification += "                                   if (my_array[a][b][c][d] " +
4524 							var_iterator->second.specific_element +
4525 							" != iterator)\n"
4526 							"                                   {\n"
4527 							"                                       result = 0.0;\n"
4528 							"                                   }\n"
4529 							"                                   iterator += " +
4530 							var_iterator->second.iterator_type + "(1);\n";
4531 			verification += iteration_loop_end;
4532 
4533 			if (false == test_compute)
4534 			{
4535 				execute_draw_test(tested_shader_type, function_definition, function_use, verification);
4536 			}
4537 			else
4538 			{
4539 				execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
4540 			}
4541 
4542 			/* Deallocate any resources used. */
4543 			this->delete_objects();
4544 		} /* if var_type iterator found */
4545 		else
4546 		{
4547 			TCU_FAIL("Type not found.");
4548 		}
4549 	} /* for (int var_type_index = 0; ...) */
4550 }
4551 
4552 /** Executes test for compute program
4553  *
4554  * @tparam API                Tested API descriptor
4555  *
4556  * @param tested_shader_type  The type of shader that is being tested
4557  * @param function_definition Definition used to prepare shader
4558  * @param function_use        Snippet that makes use of defined function
4559  * @param verification        Snippet that verifies results
4560  **/
4561 template <class API>
execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)4562 void InteractionFunctionCalls1<API>::execute_dispatch_test(
4563 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4564 	const std::string& function_use, const std::string& verification)
4565 {
4566 	const std::string& compute_shader_source =
4567 		prepare_compute_shader(tested_shader_type, function_definition, function_use, verification);
4568 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
4569 
4570 	this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string,
4571 								compute_shader_source, false, false);
4572 
4573 	/* We are now ready to verify whether the returned size is correct. */
4574 	unsigned char buffer[4]				= { 0 };
4575 	glw::GLuint   framebuffer_object_id = 0;
4576 	glw::GLint	location				= -1;
4577 	glw::GLuint   texture_object_id		= 0;
4578 	glw::GLuint   vao_id				= 0;
4579 
4580 	gl.useProgram(this->program_object_id);
4581 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
4582 
4583 	gl.genTextures(1, &texture_object_id);
4584 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
4585 
4586 	gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
4587 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
4588 
4589 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
4590 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
4591 
4592 	gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
4593 						GL_WRITE_ONLY, GL_RGBA8);
4594 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed.");
4595 
4596 	location = gl.getUniformLocation(this->program_object_id, "uni_image");
4597 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
4598 
4599 	if (-1 == location)
4600 	{
4601 		TCU_FAIL("Uniform is inactive");
4602 	}
4603 
4604 	gl.uniform1i(location, 0 /* image unit */);
4605 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
4606 
4607 	gl.genVertexArrays(1, &vao_id);
4608 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
4609 
4610 	gl.bindVertexArray(vao_id);
4611 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
4612 
4613 	gl.dispatchCompute(1, 1, 1);
4614 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4615 
4616 	gl.genFramebuffers(1, &framebuffer_object_id);
4617 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
4618 
4619 	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
4620 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
4621 
4622 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
4623 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
4624 
4625 	gl.viewport(0, 0, 1, 1);
4626 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
4627 
4628 	gl.readBuffer(GL_COLOR_ATTACHMENT0);
4629 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
4630 
4631 	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
4632 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
4633 
4634 	if (buffer[0] != 255)
4635 	{
4636 		TCU_FAIL("Invalid array size was returned.");
4637 	}
4638 
4639 	/* Delete generated objects. */
4640 	gl.deleteTextures(1, &texture_object_id);
4641 	gl.deleteFramebuffers(1, &framebuffer_object_id);
4642 	gl.deleteVertexArrays(1, &vao_id);
4643 	GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
4644 }
4645 
4646 /** Executes test for draw program
4647  *
4648  * @tparam API                Tested API descriptor
4649  *
4650  * @param tested_shader_type  The type of shader that is being tested
4651  * @param function_definition Definition used to prepare shader
4652  * @param function_use        Snippet that makes use of defined function
4653  * @param verification        Snippet that verifies results
4654  **/
4655 template <class API>
execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)4656 void InteractionFunctionCalls1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
4657 													   const std::string&						  function_definition,
4658 													   const std::string& function_use, const std::string& verification)
4659 {
4660 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
4661 
4662 	if (API::USE_ALL_SHADER_STAGES)
4663 	{
4664 		const std::string& compute_shader_source = empty_string;
4665 		const std::string& fragment_shader_source =
4666 			this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
4667 		const std::string& geometry_shader_source =
4668 			this->prepare_geometry_shader(tested_shader_type, function_definition, function_use, verification);
4669 		const std::string& tess_ctrl_shader_source =
4670 			this->prepare_tess_ctrl_shader(tested_shader_type, function_definition, function_use, verification);
4671 		const std::string& tess_eval_shader_source =
4672 			this->prepare_tess_eval_shader(tested_shader_type, function_definition, function_use, verification);
4673 		const std::string& vertex_shader_source =
4674 			this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
4675 
4676 		switch (tested_shader_type)
4677 		{
4678 		case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
4679 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4680 			this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
4681 			break;
4682 
4683 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4684 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4685 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
4686 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4687 			this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
4688 										geometry_shader_source, fragment_shader_source, compute_shader_source, false,
4689 										false);
4690 			break;
4691 
4692 		default:
4693 			TCU_FAIL("Invalid enum");
4694 			break;
4695 		}
4696 	}
4697 	else
4698 	{
4699 		const std::string& fragment_shader_source =
4700 			this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
4701 		const std::string& vertex_shader_source =
4702 			this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
4703 
4704 		this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
4705 	}
4706 
4707 	/* We are now ready to verify whether the returned size is correct. */
4708 	unsigned char buffer[4]				= { 0 };
4709 	glw::GLuint   framebuffer_object_id = 0;
4710 	glw::GLuint   texture_object_id		= 0;
4711 	glw::GLuint   vao_id				= 0;
4712 
4713 	gl.useProgram(this->program_object_id);
4714 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
4715 
4716 	gl.genTextures(1, &texture_object_id);
4717 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
4718 
4719 	gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
4720 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
4721 
4722 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
4723 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
4724 
4725 	gl.genFramebuffers(1, &framebuffer_object_id);
4726 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
4727 
4728 	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
4729 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
4730 
4731 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
4732 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
4733 
4734 	gl.viewport(0, 0, 1, 1);
4735 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
4736 
4737 	gl.genVertexArrays(1, &vao_id);
4738 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
4739 
4740 	gl.bindVertexArray(vao_id);
4741 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
4742 
4743 	switch (tested_shader_type)
4744 	{
4745 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
4746 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4747 		gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
4748 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4749 		break;
4750 
4751 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
4752 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4753 		/* Tesselation patch set up */
4754 		gl.patchParameteri(GL_PATCH_VERTICES, 1);
4755 		GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
4756 
4757 		gl.drawArrays(GL_PATCHES, 0, 1);
4758 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4759 		break;
4760 
4761 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4762 		gl.drawArrays(GL_POINTS, 0, 1);
4763 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
4764 		break;
4765 
4766 	default:
4767 		TCU_FAIL("Invalid enum");
4768 		break;
4769 	}
4770 
4771 	gl.readBuffer(GL_COLOR_ATTACHMENT0);
4772 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
4773 
4774 	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
4775 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
4776 
4777 	if (buffer[0] != 255)
4778 	{
4779 		TCU_FAIL("Invalid array size was returned.");
4780 	}
4781 
4782 	/* Delete generated objects. */
4783 	gl.bindTexture(GL_TEXTURE_2D, 0);
4784 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4785 	gl.bindVertexArray(0);
4786 	gl.deleteTextures(1, &texture_object_id);
4787 	gl.deleteFramebuffers(1, &framebuffer_object_id);
4788 	gl.deleteVertexArrays(1, &vao_id);
4789 	GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
4790 }
4791 
4792 /** Prepare shader
4793  *
4794  * @tparam API                Tested API descriptor
4795  *
4796  * @param tested_shader_type  The type of shader that is being tested
4797  * @param function_definition Definition used to prepare shader
4798  * @param function_use        Snippet that makes use of defined function
4799  * @param verification        Snippet that verifies results
4800  **/
4801 template <class API>
prepare_compute_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)4802 std::string InteractionFunctionCalls1<API>::prepare_compute_shader(
4803 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4804 	const std::string& function_use, const std::string& verification)
4805 {
4806 	std::string compute_shader_source;
4807 
4808 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
4809 	{
4810 		compute_shader_source = "writeonly uniform image2D uni_image;\n"
4811 								"\n";
4812 
4813 		/* User-defined function definition. */
4814 		compute_shader_source += function_definition;
4815 		compute_shader_source += "\n\n";
4816 
4817 		/* Main function definition. */
4818 		compute_shader_source += shader_start;
4819 		compute_shader_source += function_use;
4820 		compute_shader_source += "\n\n";
4821 		compute_shader_source += verification;
4822 		compute_shader_source += "\n\n";
4823 		compute_shader_source += "\n"
4824 								 "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
4825 								 "}\n"
4826 								 "\n";
4827 	}
4828 
4829 	return compute_shader_source;
4830 }
4831 
4832 /** Prepare shader
4833  *
4834  * @tparam API                Tested API descriptor
4835  *
4836  * @param tested_shader_type  The type of shader that is being tested
4837  * @param function_definition Definition used to prepare shader
4838  * @param function_use        Snippet that makes use of defined function
4839  * @param verification        Snippet that verifies results
4840  **/
4841 template <class API>
prepare_fragment_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)4842 std::string InteractionFunctionCalls1<API>::prepare_fragment_shader(
4843 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4844 	const std::string& function_use, const std::string& verification)
4845 {
4846 	std::string fragment_shader_source;
4847 
4848 	switch (tested_shader_type)
4849 	{
4850 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4851 		break;
4852 
4853 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4854 		fragment_shader_source = "out vec4 colour;\n\n";
4855 
4856 		/* User-defined function definition. */
4857 		fragment_shader_source += function_definition;
4858 		fragment_shader_source += "\n\n";
4859 
4860 		/* Main function definition. */
4861 		fragment_shader_source += shader_start;
4862 		fragment_shader_source += function_use;
4863 		fragment_shader_source += "\n\n";
4864 		fragment_shader_source += verification;
4865 		fragment_shader_source += "\n\n";
4866 		fragment_shader_source += "    colour = vec4(result);\n";
4867 		fragment_shader_source += shader_end;
4868 		break;
4869 
4870 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4871 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4872 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4873 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4874 		fragment_shader_source = "in float fs_result;\n\n"
4875 								 "out vec4 colour;\n\n"
4876 								 "void main()\n"
4877 								 "{\n"
4878 								 "    colour =  vec4(fs_result);\n"
4879 								 "}\n"
4880 								 "\n";
4881 		break;
4882 
4883 	default:
4884 		TCU_FAIL("Unrecognized shader object type.");
4885 		break;
4886 	}
4887 
4888 	return fragment_shader_source;
4889 }
4890 
4891 /** Prepare shader
4892  *
4893  * @tparam API                Tested API descriptor
4894  *
4895  * @param tested_shader_type  The type of shader that is being tested
4896  * @param function_definition Definition used to prepare shader
4897  * @param function_use        Snippet that makes use of defined function
4898  * @param verification        Snippet that verifies results
4899  **/
4900 template <class API>
prepare_geometry_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)4901 std::string InteractionFunctionCalls1<API>::prepare_geometry_shader(
4902 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4903 	const std::string& function_use, const std::string& verification)
4904 {
4905 	std::string geometry_shader_source;
4906 
4907 	switch (tested_shader_type)
4908 	{
4909 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4910 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4911 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
4912 		break;
4913 
4914 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
4915 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
4916 		geometry_shader_source = "layout(points)                           in;\n"
4917 								 "layout(triangle_strip, max_vertices = 4) out;\n"
4918 								 "\n"
4919 								 "in  float tes_result[];\n"
4920 								 "out float fs_result;\n"
4921 								 "\n"
4922 								 "void main()\n"
4923 								 "{\n"
4924 								 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
4925 								 "    fs_result    = tes_result[0];\n"
4926 								 "    EmitVertex();\n"
4927 								 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
4928 								 "    fs_result    = tes_result[0];\n"
4929 								 "    EmitVertex();\n"
4930 								 "    gl_Position  = vec4(1, -1, 0, 1);\n"
4931 								 "    fs_result    = tes_result[0];\n"
4932 								 "    EmitVertex();\n"
4933 								 "    gl_Position  = vec4(1, 1, 0, 1);\n"
4934 								 "    fs_result    = tes_result[0];\n"
4935 								 "    EmitVertex();\n"
4936 								 "}\n";
4937 		break;
4938 
4939 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
4940 		geometry_shader_source = "layout(points)                           in;\n"
4941 								 "layout(triangle_strip, max_vertices = 4) out;\n"
4942 								 "\n"
4943 								 "out float fs_result;\n"
4944 								 "\n";
4945 
4946 		/* User-defined function definition. */
4947 		geometry_shader_source += function_definition;
4948 		geometry_shader_source += "\n\n";
4949 
4950 		/* Main function definition. */
4951 		geometry_shader_source += shader_start;
4952 		geometry_shader_source += function_use;
4953 		geometry_shader_source += "\n\n";
4954 		geometry_shader_source += verification;
4955 		geometry_shader_source += "\n\n";
4956 		geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
4957 								  "    fs_result    = result;\n"
4958 								  "    EmitVertex();\n"
4959 								  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
4960 								  "    fs_result    = result;\n"
4961 								  "    EmitVertex();\n"
4962 								  "    gl_Position  = vec4(1, -1, 0, 1);\n"
4963 								  "    fs_result    = result;\n"
4964 								  "    EmitVertex();\n"
4965 								  "    gl_Position  = vec4(1, 1, 0, 1);\n"
4966 								  "    fs_result    = result;\n"
4967 								  "    EmitVertex();\n"
4968 								  "}\n";
4969 		break;
4970 
4971 	default:
4972 		TCU_FAIL("Unrecognized shader object type.");
4973 		break;
4974 	}
4975 
4976 	return geometry_shader_source;
4977 }
4978 
4979 /** Prepare shader
4980  *
4981  * @tparam API                Tested API descriptor
4982  *
4983  * @param tested_shader_type  The type of shader that is being tested
4984  * @param function_definition Definition used to prepare shader
4985  * @param function_use        Snippet that makes use of defined function
4986  * @param verification        Snippet that verifies results
4987  **/
4988 template <class API>
prepare_tess_ctrl_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)4989 std::string InteractionFunctionCalls1<API>::prepare_tess_ctrl_shader(
4990 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
4991 	const std::string& function_use, const std::string& verification)
4992 {
4993 	std::string tess_ctrl_shader_source;
4994 
4995 	switch (tested_shader_type)
4996 	{
4997 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
4998 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
4999 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
5000 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
5001 		break;
5002 
5003 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
5004 		tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
5005 								  "\n"
5006 								  "out float tcs_result[];\n"
5007 								  "\n";
5008 
5009 		/* User-defined function definition. */
5010 		tess_ctrl_shader_source += function_definition;
5011 		tess_ctrl_shader_source += "\n\n";
5012 
5013 		/* Main function definition. */
5014 		tess_ctrl_shader_source += shader_start;
5015 		tess_ctrl_shader_source += function_use;
5016 		tess_ctrl_shader_source += "\n\n";
5017 		tess_ctrl_shader_source += verification;
5018 		tess_ctrl_shader_source += "\n\n";
5019 		tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
5020 								   "\n"
5021 								   "    gl_TessLevelOuter[0] = 1.0;\n"
5022 								   "    gl_TessLevelOuter[1] = 1.0;\n"
5023 								   "    gl_TessLevelOuter[2] = 1.0;\n"
5024 								   "    gl_TessLevelOuter[3] = 1.0;\n"
5025 								   "    gl_TessLevelInner[0] = 1.0;\n"
5026 								   "    gl_TessLevelInner[1] = 1.0;\n"
5027 								   "}\n";
5028 		break;
5029 
5030 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
5031 		tess_ctrl_shader_source = default_tc_shader_source;
5032 		break;
5033 
5034 	default:
5035 		TCU_FAIL("Unrecognized shader object type.");
5036 		break;
5037 	}
5038 
5039 	return tess_ctrl_shader_source;
5040 }
5041 
5042 /** Prepare shader
5043  *
5044  * @tparam API                Tested API descriptor
5045  *
5046  * @param tested_shader_type  The type of shader that is being tested
5047  * @param function_definition Definition used to prepare shader
5048  * @param function_use        Snippet that makes use of defined function
5049  * @param verification        Snippet that verifies results
5050  **/
5051 template <class API>
prepare_tess_eval_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)5052 std::string InteractionFunctionCalls1<API>::prepare_tess_eval_shader(
5053 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
5054 	const std::string& function_use, const std::string& verification)
5055 {
5056 	std::string tess_eval_shader_source;
5057 
5058 	switch (tested_shader_type)
5059 	{
5060 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
5061 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
5062 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
5063 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
5064 		break;
5065 
5066 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
5067 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
5068 								  "\n"
5069 								  "in  float tcs_result[];\n"
5070 								  "out float tes_result;\n"
5071 								  "\n"
5072 								  "void main()\n"
5073 								  "{\n"
5074 								  "    tes_result = tcs_result[0];\n"
5075 								  "}\n";
5076 		break;
5077 
5078 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
5079 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
5080 								  "\n"
5081 								  "out float tes_result;\n"
5082 								  "\n";
5083 
5084 		/* User-defined function definition. */
5085 		tess_eval_shader_source += function_definition;
5086 		tess_eval_shader_source += "\n\n";
5087 
5088 		/* Main function definition. */
5089 		tess_eval_shader_source += shader_start;
5090 		tess_eval_shader_source += function_use;
5091 		tess_eval_shader_source += "\n\n";
5092 		tess_eval_shader_source += verification;
5093 		tess_eval_shader_source += "\n\n";
5094 		tess_eval_shader_source += "    tes_result = result;\n"
5095 								   "}\n";
5096 		break;
5097 
5098 	default:
5099 		TCU_FAIL("Unrecognized shader object type.");
5100 		break;
5101 	}
5102 
5103 	return tess_eval_shader_source;
5104 }
5105 
5106 /** Prepare shader
5107  *
5108  * @tparam API                Tested API descriptor
5109  *
5110  * @param tested_shader_type  The type of shader that is being tested
5111  * @param function_definition Definition used to prepare shader
5112  * @param function_use        Snippet that makes use of defined function
5113  * @param verification        Snippet that verifies results
5114  **/
5115 template <class API>
prepare_vertex_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)5116 std::string InteractionFunctionCalls1<API>::prepare_vertex_shader(
5117 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
5118 	const std::string& function_use, const std::string& verification)
5119 {
5120 	std::string vertex_shader_source;
5121 
5122 	switch (tested_shader_type)
5123 	{
5124 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
5125 		break;
5126 
5127 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
5128 		vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
5129 							   "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
5130 							   "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
5131 							   "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
5132 							   "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
5133 							   "\n"
5134 							   "void main()\n"
5135 							   "{\n"
5136 							   "    gl_Position = vertex_positions[gl_VertexID];"
5137 							   "}\n\n";
5138 		break;
5139 
5140 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
5141 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
5142 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
5143 		vertex_shader_source = default_vertex_shader_source;
5144 		break;
5145 
5146 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
5147 		/* Vertex shader source. */
5148 		vertex_shader_source = "out float fs_result;\n\n";
5149 		vertex_shader_source += "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
5150 								"const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
5151 								"                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
5152 								"                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
5153 								"                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n\n";
5154 
5155 		/* User-defined function definition. */
5156 		vertex_shader_source += function_definition;
5157 		vertex_shader_source += "\n\n";
5158 
5159 		/* Main function definition. */
5160 		vertex_shader_source += shader_start;
5161 		vertex_shader_source += function_use;
5162 		vertex_shader_source += "\n\n";
5163 		vertex_shader_source += verification;
5164 		vertex_shader_source += "\n\n";
5165 		vertex_shader_source += "    fs_result   = result;\n"
5166 								"    gl_Position = vertex_positions[gl_VertexID];\n";
5167 		vertex_shader_source += shader_end;
5168 		break;
5169 
5170 	default:
5171 		TCU_FAIL("Unrecognized shader object type.");
5172 		break;
5173 	}
5174 
5175 	return vertex_shader_source;
5176 }
5177 
5178 /* Generates the shader source code for the InteractionFunctionCalls2
5179  * array tests, and attempts to compile each test shader, for both
5180  * vertex and fragment shaders.
5181  *
5182  * @tparam API               Tested API descriptor
5183  *
5184  * @param tested_shader_type The type of shader that is being tested
5185  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5186  */
5187 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5188 void InteractionFunctionCalls2<API>::test_shader_compilation(
5189 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5190 {
5191 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
5192 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
5193 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
5194 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
5195 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5196 
5197 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
5198 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
5199 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
5200 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
5201 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
5202 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5203 
5204 	const std::string iteration_loop_end = "                }\n"
5205 										   "            }\n"
5206 										   "        }\n"
5207 										   "    }\n";
5208 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5209 											 "    {\n"
5210 											 "        for (uint b = 0u; b < 2u; b++)\n"
5211 											 "        {\n"
5212 											 "            for (uint c = 0u; c < 2u; c++)\n"
5213 											 "            {\n"
5214 											 "                for (uint d = 0u; d < 2u; d++)\n"
5215 											 "                {\n";
5216 	const std::string multiplier_array = "const int[] multiplier_array = int[]( 1,  2,  3,  4,  5,  6,  7,  8,\n"
5217 										 "                                     11, 12, 13, 14, 15, 16, 17, 18,\n"
5218 										 "                                     21, 22, 23, 24, 25, 26, 27, 28,\n"
5219 										 "                                     31, 32, 33, 34, 35, 36, 37, 38,\n"
5220 										 "                                     41, 42, 43, 44, 45, 46, 47, 48,\n"
5221 										 "                                     51, 52, 53, 54, 55, 56, 57, 58,\n"
5222 										 "                                     61, 62, 63, 64, 65, 66, 67, 68,\n"
5223 										 "                                     71, 72, 73, 74, 75, 76, 77, 78,\n"
5224 										 "                                     81, 82, 83, 84, 85, 86, 87, 88);\n";
5225 	const glcts::test_var_type* var_types_set = var_types_set_es;
5226 	size_t						num_var_types = num_var_types_es;
5227 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5228 
5229 	if (API::USE_DOUBLE)
5230 	{
5231 		var_types_set = var_types_set_gl;
5232 		num_var_types = num_var_types_gl;
5233 	}
5234 
5235 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5236 	{
5237 		_supported_variable_types_map_const_iterator var_iterator =
5238 			supported_variable_types_map.find(var_types_set[var_type_index]);
5239 
5240 		if (var_iterator != supported_variable_types_map.end())
5241 		{
5242 			std::string function_definition;
5243 			std::string function_use;
5244 			std::string verification;
5245 
5246 			function_definition += multiplier_array;
5247 			function_definition += "void my_function(inout ";
5248 			function_definition += var_iterator->second.type;
5249 			function_definition += " inout_array[2][2][2][2]) {\n"
5250 								   "    uint i = 0u;\n";
5251 			function_definition += iteration_loop_start;
5252 			function_definition += "                                   inout_array[a][b][c][d] *= " +
5253 								   var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n";
5254 			function_definition += "                                   i+= 1u;\n";
5255 			function_definition += iteration_loop_end;
5256 			function_definition += "}";
5257 
5258 			function_use += "    float result = 1.0;\n";
5259 			function_use += "    uint iterator = 0u;\n";
5260 			function_use += "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
5261 			function_use += iteration_loop_start;
5262 			function_use += "                                   my_array[a][b][c][d] = " +
5263 							var_iterator->second.variable_type_initializer2 + ";\n";
5264 			function_use += iteration_loop_end;
5265 			function_use += "    my_function(my_array);";
5266 
5267 			verification += iteration_loop_start;
5268 			verification += "                                   if (my_array[a][b][c][d] " +
5269 							var_iterator->second.specific_element + "!= " + var_iterator->second.iterator_type +
5270 							"(multiplier_array[iterator % 64u]))\n"
5271 							"                                   {\n"
5272 							"                                       result = 0.0;\n"
5273 							"                                   }\n"
5274 							"                                   iterator += 1u;\n";
5275 			verification += iteration_loop_end;
5276 
5277 			if (false == test_compute)
5278 			{
5279 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5280 			}
5281 			else
5282 			{
5283 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5284 			}
5285 
5286 			/* Deallocate any resources used. */
5287 			this->delete_objects();
5288 		} /* if var_type iterator found */
5289 		else
5290 		{
5291 			TCU_FAIL("Type not found.");
5292 		}
5293 	} /* for (int var_type_index = 0; ...) */
5294 }
5295 
5296 /* Generates the shader source code for the InteractionArgumentAliasing1
5297  * array tests, and attempts to compile each test shader, for both
5298  * vertex and fragment shaders.
5299  *
5300  * @tparam API               Tested API descriptor
5301  *
5302  * @param tested_shader_type The type of shader that is being tested
5303  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5304  */
5305 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5306 void InteractionArgumentAliasing1<API>::test_shader_compilation(
5307 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5308 {
5309 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5310 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5311 
5312 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5313 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5314 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5315 
5316 	const std::string iteration_loop_end = "                }\n"
5317 										   "            }\n"
5318 										   "        }\n"
5319 										   "    }\n";
5320 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5321 											 "    {\n"
5322 											 "        for (uint b = 0u; b < 2u; b++)\n"
5323 											 "        {\n"
5324 											 "            for (uint c = 0u; c < 2u; c++)\n"
5325 											 "            {\n"
5326 											 "                for (uint d = 0u; d < 2u; d++)\n"
5327 											 "                {\n";
5328 	const glcts::test_var_type* var_types_set = var_types_set_es;
5329 	size_t						num_var_types = num_var_types_es;
5330 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5331 
5332 	if (API::USE_DOUBLE)
5333 	{
5334 		var_types_set = var_types_set_gl;
5335 		num_var_types = num_var_types_gl;
5336 	}
5337 
5338 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5339 	{
5340 		_supported_variable_types_map_const_iterator var_iterator =
5341 			supported_variable_types_map.find(var_types_set[var_type_index]);
5342 
5343 		if (var_iterator != supported_variable_types_map.end())
5344 		{
5345 			std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n";
5346 
5347 			std::string function_definition;
5348 			std::string function_use;
5349 			std::string verification;
5350 
5351 			function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5352 			function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5353 			function_definition += "{\n";
5354 			function_definition += "    " + iteration_loop_start;
5355 			function_definition +=
5356 				"                               x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
5357 			function_definition += "    " + iteration_loop_end;
5358 			function_definition += "\n";
5359 			function_definition += "    " + iteration_loop_start;
5360 			function_definition += "                                   if(y[a][b][c][d]";
5361 			if (var_iterator->second.type == "mat4") // mat4 comparison
5362 			{
5363 				function_definition += "[0][0]";
5364 				function_definition += " != float";
5365 			}
5366 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5367 			{
5368 				function_definition += "[0][0]";
5369 				function_definition += " != double";
5370 			}
5371 			else
5372 			{
5373 				function_definition += " != ";
5374 				function_definition += var_iterator->second.type;
5375 			}
5376 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5377 			function_definition += "    " + iteration_loop_end;
5378 			function_definition += "  return true;\n";
5379 			function_definition += "}";
5380 
5381 			function_use += "    " + array_declaration;
5382 			function_use += "    " + iteration_loop_start;
5383 			function_use += "                                   z[a][b][c][d] = ";
5384 			function_use += var_iterator->second.type;
5385 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5386 			function_use += "    " + iteration_loop_end;
5387 
5388 			verification += "    float result = 0.0;\n";
5389 			verification += "    if(gfunc(z, z) == true)\n";
5390 			verification += "    {\n";
5391 			verification += "        result = 1.0;\n\n";
5392 			verification += "    }\n";
5393 			verification += "    else\n";
5394 			verification += "    {\n";
5395 			verification += "        result = 0.0;\n\n";
5396 			verification += "    }\n";
5397 
5398 			if (false == test_compute)
5399 			{
5400 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5401 			}
5402 			else
5403 			{
5404 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5405 			}
5406 
5407 			/* Deallocate any resources used. */
5408 			this->delete_objects();
5409 		} /* if var_type iterator found */
5410 		else
5411 		{
5412 			TCU_FAIL("Type not found.");
5413 		}
5414 	}
5415 }
5416 
5417 /* Generates the shader source code for the InteractionArgumentAliasing2
5418  * array tests, and attempts to compile each test shader, for both
5419  * vertex and fragment shaders.
5420  *
5421  * @tparam API               Tested API descriptor
5422  *
5423  * @param tested_shader_type The type of shader that is being tested
5424  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5425  */
5426 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5427 void InteractionArgumentAliasing2<API>::test_shader_compilation(
5428 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5429 {
5430 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5431 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5432 
5433 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5434 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5435 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5436 
5437 	const std::string iteration_loop_end = "                }\n"
5438 										   "            }\n"
5439 										   "        }\n"
5440 										   "    }\n";
5441 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5442 											 "    {\n"
5443 											 "        for (uint b = 0u; b < 2u; b++)\n"
5444 											 "        {\n"
5445 											 "            for (uint c = 0u; c < 2u; c++)\n"
5446 											 "            {\n"
5447 											 "                for (uint d = 0u; d < 2u; d++)\n"
5448 											 "                {\n";
5449 	const glcts::test_var_type* var_types_set = var_types_set_es;
5450 	size_t						num_var_types = num_var_types_es;
5451 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5452 
5453 	if (API::USE_DOUBLE)
5454 	{
5455 		var_types_set = var_types_set_gl;
5456 		num_var_types = num_var_types_gl;
5457 	}
5458 
5459 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5460 	{
5461 		_supported_variable_types_map_const_iterator var_iterator =
5462 			supported_variable_types_map.find(var_types_set[var_type_index]);
5463 
5464 		if (var_iterator != supported_variable_types_map.end())
5465 		{
5466 			std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n";
5467 
5468 			std::string function_definition;
5469 			std::string function_use;
5470 			std::string verification;
5471 
5472 			function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5473 			function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5474 			function_definition += "{\n";
5475 			function_definition += "    " + iteration_loop_start;
5476 			function_definition +=
5477 				"                                   y[a][b][c][d] = " + var_iterator->second.type +
5478 				"(123);\n";
5479 			function_definition += "    " + iteration_loop_end;
5480 			function_definition += "\n";
5481 			function_definition += "    " + iteration_loop_start;
5482 			function_definition += "                                   if(x[a][b][c][d]";
5483 			if (var_iterator->second.type == "mat4") // mat4 comparison
5484 			{
5485 				function_definition += "[0][0]";
5486 				function_definition += " != float";
5487 			}
5488 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5489 			{
5490 				function_definition += "[0][0]";
5491 				function_definition += " != double";
5492 			}
5493 			else
5494 			{
5495 				function_definition += " != ";
5496 				function_definition += var_iterator->second.type;
5497 			}
5498 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5499 			function_definition += "    " + iteration_loop_end;
5500 			function_definition += "  return true;\n";
5501 			function_definition += "}";
5502 
5503 			function_use += "    " + array_declaration;
5504 			function_use += "    " + iteration_loop_start;
5505 			function_use += "                                   z[a][b][c][d] = ";
5506 			function_use += var_iterator->second.type;
5507 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5508 			function_use += "    " + iteration_loop_end;
5509 
5510 			verification += "    float result = 0.0;\n";
5511 			verification += "    if(gfunc(z, z) == true)\n";
5512 			verification += "    {\n";
5513 			verification += "        result = 1.0;\n\n";
5514 			verification += "    }\n";
5515 			verification += "    else\n";
5516 			verification += "    {\n";
5517 			verification += "        result = 0.0;\n\n";
5518 			verification += "    }\n";
5519 
5520 			if (false == test_compute)
5521 			{
5522 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5523 			}
5524 			else
5525 			{
5526 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5527 			}
5528 
5529 			/* Deallocate any resources used. */
5530 			this->delete_objects();
5531 		} /* if var_type iterator found */
5532 		else
5533 		{
5534 			TCU_FAIL("Type not found.");
5535 		}
5536 	}
5537 }
5538 
5539 /* Generates the shader source code for the InteractionArgumentAliasing3
5540  * array tests, and attempts to compile each test shader, for both
5541  * vertex and fragment shaders.
5542  *
5543  * @tparam API               Tested API descriptor
5544  *
5545  * @param tested_shader_type The type of shader that is being tested
5546  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5547  */
5548 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5549 void InteractionArgumentAliasing3<API>::test_shader_compilation(
5550 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5551 {
5552 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5553 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5554 
5555 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5556 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5557 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5558 
5559 	const std::string iteration_loop_end = "                }\n"
5560 										   "            }\n"
5561 										   "        }\n"
5562 										   "    }\n";
5563 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5564 											 "    {\n"
5565 											 "        for (uint b = 0u; b < 2u; b++)\n"
5566 											 "        {\n"
5567 											 "            for (uint c = 0u; c < 2u; c++)\n"
5568 											 "            {\n"
5569 											 "                for (uint d = 0u; d < 2u; d++)\n"
5570 											 "                {\n";
5571 	const glcts::test_var_type* var_types_set = var_types_set_es;
5572 	size_t						num_var_types = num_var_types_es;
5573 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5574 
5575 	if (API::USE_DOUBLE)
5576 	{
5577 		var_types_set = var_types_set_gl;
5578 		num_var_types = num_var_types_gl;
5579 	}
5580 
5581 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5582 	{
5583 		_supported_variable_types_map_const_iterator var_iterator =
5584 			supported_variable_types_map.find(var_types_set[var_type_index]);
5585 
5586 		if (var_iterator != supported_variable_types_map.end())
5587 		{
5588 			std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n";
5589 
5590 			std::string function_definition;
5591 			std::string function_use;
5592 			std::string verification;
5593 
5594 			function_definition += "bool gfunc(out " + var_iterator->second.type + " x[2][2][2][2], ";
5595 			function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5596 			function_definition += "{\n";
5597 			function_definition += "    " + iteration_loop_start;
5598 			function_definition +=
5599 				"                                   x[a][b][c][d] = " + var_iterator->second.type +
5600 				"(123);\n";
5601 			function_definition += "    " + iteration_loop_end;
5602 			function_definition += "\n";
5603 			function_definition += "    " + iteration_loop_start;
5604 			function_definition += "                                   if(y[a][b][c][d]";
5605 			if (var_iterator->second.type == "mat4") // mat4 comparison
5606 			{
5607 				function_definition += "[0][0]";
5608 				function_definition += " != float";
5609 			}
5610 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5611 			{
5612 				function_definition += "[0][0]";
5613 				function_definition += " != double";
5614 			}
5615 			else
5616 			{
5617 				function_definition += " != ";
5618 				function_definition += var_iterator->second.type;
5619 			}
5620 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5621 			function_definition += "    " + iteration_loop_end;
5622 			function_definition += "  return true;\n";
5623 			function_definition += "}\n\n";
5624 
5625 			function_use += "    " + array_declaration;
5626 			function_use += "    " + iteration_loop_start;
5627 			function_use += "                                   z[a][b][c][d] = ";
5628 			function_use += var_iterator->second.type;
5629 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5630 			function_use += "    " + iteration_loop_end;
5631 
5632 			verification += "    float result = 0.0;\n";
5633 			verification += "    if(gfunc(z, z) == true)\n";
5634 			verification += "    {\n";
5635 			verification += "        result = 1.0;\n\n";
5636 			verification += "    }\n";
5637 			verification += "    else\n";
5638 			verification += "    {\n";
5639 			verification += "        result = 0.0;\n\n";
5640 			verification += "    }\n";
5641 
5642 			if (false == test_compute)
5643 			{
5644 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5645 			}
5646 			else
5647 			{
5648 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5649 			}
5650 
5651 			/* Deallocate any resources used. */
5652 			this->delete_objects();
5653 		} /* if var_type iterator found */
5654 		else
5655 		{
5656 			TCU_FAIL("Type not found.");
5657 		}
5658 	}
5659 }
5660 
5661 /* Generates the shader source code for the InteractionArgumentAliasing4
5662  * array tests, and attempts to compile each test shader, for both
5663  * vertex and fragment shaders.
5664  *
5665  * @tparam API               Tested API descriptor
5666  *
5667  * @param tested_shader_type The type of shader that is being tested
5668  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5669  */
5670 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5671 void InteractionArgumentAliasing4<API>::test_shader_compilation(
5672 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5673 {
5674 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5675 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5676 
5677 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5678 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5679 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5680 
5681 	const std::string iteration_loop_end = "                }\n"
5682 										   "            }\n"
5683 										   "        }\n"
5684 										   "    }\n";
5685 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5686 											 "    {\n"
5687 											 "        for (uint b = 0u; b < 2u; b++)\n"
5688 											 "        {\n"
5689 											 "            for (uint c = 0u; c < 2u; c++)\n"
5690 											 "            {\n"
5691 											 "                for (uint d = 0u; d < 2u; d++)\n"
5692 											 "                {\n";
5693 	const glcts::test_var_type* var_types_set = var_types_set_es;
5694 	size_t						num_var_types = num_var_types_es;
5695 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5696 
5697 	if (API::USE_DOUBLE)
5698 	{
5699 		var_types_set = var_types_set_gl;
5700 		num_var_types = num_var_types_gl;
5701 	}
5702 
5703 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5704 	{
5705 		_supported_variable_types_map_const_iterator var_iterator =
5706 			supported_variable_types_map.find(var_types_set[var_type_index]);
5707 
5708 		if (var_iterator != supported_variable_types_map.end())
5709 		{
5710 			std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n";
5711 
5712 			std::string function_definition;
5713 			std::string function_use;
5714 			std::string verification;
5715 
5716 			function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5717 			function_definition += "out " + var_iterator->second.type + " y[2][2][2][2])\n";
5718 			function_definition += "{\n";
5719 			function_definition += "    " + iteration_loop_start;
5720 			function_definition +=
5721 				"                                   y[a][b][c][d] = " + var_iterator->second.type +
5722 				"(123);\n";
5723 			function_definition += "    " + iteration_loop_end;
5724 			function_definition += "\n";
5725 			function_definition += "    " + iteration_loop_start;
5726 			function_definition += "                                   if(x[a][b][c][d]";
5727 			if (var_iterator->second.type == "mat4") // mat4 comparison
5728 			{
5729 				function_definition += "[0][0]";
5730 				function_definition += " != float";
5731 			}
5732 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5733 			{
5734 				function_definition += "[0][0]";
5735 				function_definition += " != double";
5736 			}
5737 			else
5738 			{
5739 				function_definition += " != ";
5740 				function_definition += var_iterator->second.type;
5741 			}
5742 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5743 			function_definition += "    " + iteration_loop_end;
5744 			function_definition += "  return true;\n";
5745 			function_definition += "}\n\n";
5746 
5747 			function_use += "    " + array_declaration;
5748 			function_use += "    " + iteration_loop_start;
5749 			function_use += "                                   z[a][b][c][d] = ";
5750 			function_use += var_iterator->second.type;
5751 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5752 			function_use += "    " + iteration_loop_end;
5753 
5754 			verification += "    float result = 0.0;\n";
5755 			verification += "    if(gfunc(z, z) == true)\n";
5756 			verification += "    {\n";
5757 			verification += "        result = 1.0;\n\n";
5758 			verification += "    }\n";
5759 			verification += "    else\n";
5760 			verification += "    {\n";
5761 			verification += "        result = 0.0;\n\n";
5762 			verification += "    }\n";
5763 
5764 			if (false == test_compute)
5765 			{
5766 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5767 			}
5768 			else
5769 			{
5770 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5771 			}
5772 
5773 			/* Deallocate any resources used. */
5774 			this->delete_objects();
5775 		} /* if var_type iterator found */
5776 		else
5777 		{
5778 			TCU_FAIL("Type not found.");
5779 		}
5780 	}
5781 }
5782 
5783 /* Generates the shader source code for the InteractionArgumentAliasing3
5784  * array tests, and attempts to compile each test shader, for both
5785  * vertex and fragment shaders.
5786  *
5787  * @tparam API               Tested API descriptor
5788  *
5789  * @param tested_shader_type The type of shader that is being tested
5790  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5791  */
5792 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5793 void InteractionArgumentAliasing5<API>::test_shader_compilation(
5794 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5795 {
5796 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5797 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5798 
5799 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5800 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5801 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5802 
5803 	const std::string iteration_loop_end = "                }\n"
5804 										   "            }\n"
5805 										   "        }\n"
5806 										   "    }\n";
5807 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5808 											 "    {\n"
5809 											 "        for (uint b = 0u; b < 2u; b++)\n"
5810 											 "        {\n"
5811 											 "            for (uint c = 0u; c < 2u; c++)\n"
5812 											 "            {\n"
5813 											 "                for (uint d = 0u; d < 2u; d++)\n"
5814 											 "                {\n";
5815 	const glcts::test_var_type* var_types_set = var_types_set_es;
5816 	size_t						num_var_types = num_var_types_es;
5817 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5818 
5819 	if (API::USE_DOUBLE)
5820 	{
5821 		var_types_set = var_types_set_gl;
5822 		num_var_types = num_var_types_gl;
5823 	}
5824 
5825 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5826 	{
5827 		_supported_variable_types_map_const_iterator var_iterator =
5828 			supported_variable_types_map.find(var_types_set[var_type_index]);
5829 
5830 		if (var_iterator != supported_variable_types_map.end())
5831 		{
5832 			std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n";
5833 
5834 			std::string function_definition;
5835 			std::string function_use;
5836 			std::string verification;
5837 
5838 			function_definition += "bool gfunc(inout " + var_iterator->second.type + " x[2][2][2][2], ";
5839 			function_definition += var_iterator->second.type + " y[2][2][2][2])\n";
5840 			function_definition += "{\n";
5841 			function_definition += "    " + iteration_loop_start;
5842 			function_definition +=
5843 				"                                   x[a][b][c][d] = " + var_iterator->second.type +
5844 				"(123);\n";
5845 			function_definition += "    " + iteration_loop_end;
5846 			function_definition += "\n";
5847 			function_definition += "    " + iteration_loop_start;
5848 			function_definition += "                                   if(y[a][b][c][d]";
5849 			if (var_iterator->second.type == "mat4") // mat4 comparison
5850 			{
5851 				function_definition += "[0][0]";
5852 				function_definition += " != float";
5853 			}
5854 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5855 			{
5856 				function_definition += "[0][0]";
5857 				function_definition += " != double";
5858 			}
5859 			else
5860 			{
5861 				function_definition += " != ";
5862 				function_definition += var_iterator->second.type;
5863 			}
5864 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5865 			function_definition += "    " + iteration_loop_end;
5866 			function_definition += "  return true;\n";
5867 			function_definition += "}\n\n";
5868 
5869 			function_use += "    " + array_declaration;
5870 			function_use += "    " + iteration_loop_start;
5871 			function_use += "                                   z[a][b][c][d] = ";
5872 			function_use += var_iterator->second.type;
5873 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5874 			function_use += "    " + iteration_loop_end;
5875 
5876 			verification += "    float result = 0.0;\n";
5877 			verification += "    if(gfunc(z, z) == true)\n";
5878 			verification += "    {\n";
5879 			verification += "        result = 1.0;\n\n";
5880 			verification += "    }\n";
5881 			verification += "    else\n";
5882 			verification += "    {\n";
5883 			verification += "        result = 0.0;\n\n";
5884 			verification += "    }\n";
5885 
5886 			if (false == test_compute)
5887 			{
5888 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
5889 			}
5890 			else
5891 			{
5892 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
5893 			}
5894 
5895 			/* Deallocate any resources used. */
5896 			this->delete_objects();
5897 		} /* if var_type iterator found */
5898 		else
5899 		{
5900 			TCU_FAIL("Type not found.");
5901 		}
5902 	}
5903 }
5904 
5905 /* Generates the shader source code for the InteractionArgumentAliasing4
5906  * array tests, and attempts to compile each test shader, for both
5907  * vertex and fragment shaders.
5908  *
5909  * @tparam API               Tested API descriptor
5910  *
5911  * @param tested_shader_type The type of shader that is being tested
5912  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
5913  */
5914 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)5915 void InteractionArgumentAliasing6<API>::test_shader_compilation(
5916 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
5917 {
5918 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
5919 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
5920 
5921 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
5922 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
5923 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
5924 
5925 	const std::string iteration_loop_end = "                }\n"
5926 										   "            }\n"
5927 										   "        }\n"
5928 										   "    }\n";
5929 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
5930 											 "    {\n"
5931 											 "        for (uint b = 0u; b < 2u; b++)\n"
5932 											 "        {\n"
5933 											 "            for (uint c = 0u; c < 2u; c++)\n"
5934 											 "            {\n"
5935 											 "                for (uint d = 0u; d < 2u; d++)\n"
5936 											 "                {\n";
5937 	const glcts::test_var_type* var_types_set = var_types_set_es;
5938 	size_t						num_var_types = num_var_types_es;
5939 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
5940 
5941 	if (API::USE_DOUBLE)
5942 	{
5943 		var_types_set = var_types_set_gl;
5944 		num_var_types = num_var_types_gl;
5945 	}
5946 
5947 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
5948 	{
5949 		_supported_variable_types_map_const_iterator var_iterator =
5950 			supported_variable_types_map.find(var_types_set[var_type_index]);
5951 
5952 		if (var_iterator != supported_variable_types_map.end())
5953 		{
5954 			std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n";
5955 
5956 			std::string function_definition;
5957 			std::string function_use;
5958 			std::string verification;
5959 
5960 			function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], ";
5961 			function_definition += "inout " + var_iterator->second.type + " y[2][2][2][2])\n";
5962 			function_definition += "{\n";
5963 			function_definition += "    " + iteration_loop_start;
5964 			function_definition +=
5965 				"                                   y[a][b][c][d] = " + var_iterator->second.type +
5966 				"(123);\n";
5967 			function_definition += "    " + iteration_loop_end;
5968 			function_definition += "\n";
5969 			function_definition += "    " + iteration_loop_start;
5970 			function_definition += "                                   if(x[a][b][c][d]";
5971 			if (var_iterator->second.type == "mat4") // mat4 comparison
5972 			{
5973 				function_definition += "[0][0]";
5974 				function_definition += " != float";
5975 			}
5976 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
5977 			{
5978 				function_definition += "[0][0]";
5979 				function_definition += " != double";
5980 			}
5981 			else
5982 			{
5983 				function_definition += " != ";
5984 				function_definition += var_iterator->second.type;
5985 			}
5986 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
5987 			function_definition += "    " + iteration_loop_end;
5988 			function_definition += "  return true;\n";
5989 			function_definition += "}\n\n";
5990 
5991 			function_use += "    " + array_declaration;
5992 			function_use += "    " + iteration_loop_start;
5993 			function_use += "                                   z[a][b][c][d] = ";
5994 			function_use += var_iterator->second.type;
5995 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
5996 			function_use += "    " + iteration_loop_end;
5997 
5998 			verification += "    float result = 0.0;\n";
5999 			verification += "    if(gfunc(z, z) == true)\n";
6000 			verification += "    {\n";
6001 			verification += "        result = 1.0;\n\n";
6002 			verification += "    }\n";
6003 			verification += "    else\n";
6004 			verification += "    {\n";
6005 			verification += "        result = 0.0;\n\n";
6006 			verification += "    }\n";
6007 
6008 			if (false == test_compute)
6009 			{
6010 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification);
6011 			}
6012 			else
6013 			{
6014 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification);
6015 			}
6016 
6017 			/* Deallocate any resources used. */
6018 			this->delete_objects();
6019 		} /* if var_type iterator found */
6020 		else
6021 		{
6022 			TCU_FAIL("Type not found.");
6023 		}
6024 	}
6025 }
6026 
6027 /* Generates the shader source code for the InteractionUniforms1
6028  * array tests, and attempts to compile each test shader, for both
6029  * vertex and fragment shaders.
6030  *
6031  * @tparam API               Tested API descriptor
6032  *
6033  * @param tested_shader_type The type of shader that is being tested
6034  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6035  */
6036 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)6037 void InteractionUniforms1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
6038 {
6039 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
6040 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6041 
6042 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
6043 															 VAR_TYPE_DOUBLE };
6044 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6045 
6046 	const glw::Functions&		gl			  = this->context_id.getRenderContext().getFunctions();
6047 	const glcts::test_var_type* var_types_set = var_types_set_es;
6048 	size_t						num_var_types = num_var_types_es;
6049 
6050 	if (API::USE_DOUBLE)
6051 	{
6052 		var_types_set = var_types_set_gl;
6053 		num_var_types = num_var_types_gl;
6054 	}
6055 
6056 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6057 	{
6058 		_supported_variable_types_map_const_iterator var_iterator =
6059 			supported_variable_types_map.find(var_types_set[var_type_index]);
6060 
6061 		if (var_iterator != supported_variable_types_map.end())
6062 		{
6063 			std::string uniform_definition;
6064 			std::string uniform_use;
6065 
6066 			uniform_definition += "uniform ";
6067 			uniform_definition += var_iterator->second.precision;
6068 			uniform_definition += " ";
6069 			uniform_definition += var_iterator->second.type;
6070 			uniform_definition += " my_uniform_1[1][1][1][1];\n\n";
6071 
6072 			uniform_use = "    float result = float(my_uniform_1[0][0][0][0]);\n";
6073 
6074 			if (API::USE_ALL_SHADER_STAGES)
6075 			{
6076 				const std::string& compute_shader_source =
6077 					this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use);
6078 				const std::string& fragment_shader_source =
6079 					this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6080 				const std::string& geometry_shader_source =
6081 					this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use);
6082 				const std::string& tess_ctrl_shader_source =
6083 					this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use);
6084 				const std::string& tess_eval_shader_source =
6085 					this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use);
6086 				const std::string& vertex_shader_source =
6087 					this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6088 
6089 				switch (tested_shader_type)
6090 				{
6091 				case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
6092 				case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6093 					this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6094 					break;
6095 
6096 				case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6097 				case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6098 				case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
6099 				case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6100 					this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
6101 												geometry_shader_source, fragment_shader_source, compute_shader_source,
6102 												false, false);
6103 					break;
6104 
6105 				default:
6106 					TCU_FAIL("Invalid enum");
6107 					break;
6108 				}
6109 			}
6110 			else
6111 			{
6112 				const std::string& fragment_shader_source =
6113 					this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6114 				const std::string& vertex_shader_source =
6115 					this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6116 
6117 				this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6118 			}
6119 
6120 			glw::GLint uniform_location = -1;
6121 
6122 			/* Make program object active. */
6123 			gl.useProgram(this->program_object_id);
6124 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
6125 
6126 			/* Get uniform location. */
6127 			uniform_location = gl.getUniformLocation(this->program_object_id, "my_uniform_1[0][0][0][0]");
6128 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
6129 
6130 			if (uniform_location == -1)
6131 			{
6132 				TCU_FAIL("Uniform is not found or is considered as not active.");
6133 			}
6134 
6135 			switch (var_type_index)
6136 			{
6137 			case 0: //float type of uniform is considered
6138 			{
6139 				glw::GLfloat uniform_value = 1.0f;
6140 
6141 				gl.uniform1f(uniform_location, uniform_value);
6142 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() failed.");
6143 
6144 				break;
6145 			}
6146 			case 1: //int type of uniform is considered
6147 			{
6148 				glw::GLint uniform_value = 1;
6149 
6150 				gl.uniform1i(uniform_location, uniform_value);
6151 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
6152 
6153 				break;
6154 			}
6155 			case 2: //uint type of uniform is considered
6156 			{
6157 				glw::GLuint uniform_value = 1;
6158 
6159 				gl.uniform1ui(uniform_location, uniform_value);
6160 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1ui() failed.");
6161 
6162 				break;
6163 			}
6164 			case 3: //double type of uniform is considered
6165 			{
6166 				glw::GLdouble uniform_value = 1.0;
6167 
6168 				gl.uniform1d(uniform_location, uniform_value);
6169 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1d() failed.");
6170 
6171 				break;
6172 			}
6173 			default:
6174 			{
6175 				TCU_FAIL("Invalid variable-type index.");
6176 
6177 				break;
6178 			}
6179 			} /* switch (var_type_index) */
6180 
6181 			/* Deallocate any resources used. */
6182 			this->delete_objects();
6183 		} /* if var_type iterator found */
6184 		else
6185 		{
6186 			TCU_FAIL("Type not found.");
6187 		}
6188 	} /* for (int var_type_index = 0; ...) */
6189 }
6190 
6191 /** Prepare shader
6192  *
6193  * @tparam API               Tested API descriptor
6194  *
6195  * @param tested_shader_type The type of shader that is being tested
6196  * @param uniform_definition Definition used to prepare shader
6197  * @param uniform_use        Snippet that use defined uniform
6198  **/
6199 template <class API>
prepare_compute_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & uniform_definition,const std::string & uniform_use)6200 std::string InteractionUniforms1<API>::prepare_compute_shader(
6201 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6202 	const std::string& uniform_use)
6203 {
6204 	std::string compute_shader_source;
6205 
6206 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
6207 	{
6208 		compute_shader_source = "writeonly uniform image2D uni_image;\n"
6209 								"\n";
6210 
6211 		/* User-defined function definition. */
6212 		compute_shader_source += uniform_definition;
6213 		compute_shader_source += "\n\n";
6214 
6215 		/* Main function definition. */
6216 		compute_shader_source += shader_start;
6217 		compute_shader_source += uniform_use;
6218 		compute_shader_source += "\n\n";
6219 		compute_shader_source += "\n"
6220 								 "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
6221 								 "}\n"
6222 								 "\n";
6223 	}
6224 
6225 	return compute_shader_source;
6226 }
6227 
6228 /** Prepare shader
6229  *
6230  * @tparam API               Tested API descriptor
6231  *
6232  * @param tested_shader_type The type of shader that is being tested
6233  * @param uniform_definition Definition used to prepare shader
6234  * @param uniform_use        Snippet that use defined uniform
6235  **/
6236 template <class API>
prepare_fragment_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & uniform_definition,const std::string & uniform_use)6237 std::string InteractionUniforms1<API>::prepare_fragment_shader(
6238 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6239 	const std::string& uniform_use)
6240 {
6241 	std::string fragment_shader_source;
6242 
6243 	switch (tested_shader_type)
6244 	{
6245 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6246 		break;
6247 
6248 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6249 		fragment_shader_source = "out vec4 colour;\n\n";
6250 
6251 		/* User-defined function definition. */
6252 		fragment_shader_source += uniform_definition;
6253 		fragment_shader_source += "\n\n";
6254 
6255 		/* Main function definition. */
6256 		fragment_shader_source += shader_start;
6257 		fragment_shader_source += uniform_use;
6258 		fragment_shader_source += "\n\n";
6259 		fragment_shader_source += "    colour = vec4(result);\n";
6260 		fragment_shader_source += shader_end;
6261 		break;
6262 
6263 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6264 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6265 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6266 		fragment_shader_source = "in float fs_result;\n\n"
6267 								 "out vec4 colour;\n\n"
6268 								 "void main()\n"
6269 								 "{\n"
6270 								 "    colour =  vec4(fs_result);\n"
6271 								 "}\n"
6272 								 "\n";
6273 		break;
6274 
6275 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6276 		fragment_shader_source = default_fragment_shader_source;
6277 		break;
6278 
6279 	default:
6280 		TCU_FAIL("Unrecognized shader object type.");
6281 		break;
6282 	}
6283 
6284 	return fragment_shader_source;
6285 }
6286 
6287 /** Prepare shader
6288  *
6289  * @tparam API               Tested API descriptor
6290  *
6291  * @param tested_shader_type The type of shader that is being tested
6292  * @param uniform_definition Definition used to prepare shader
6293  * @param uniform_use        Snippet that use defined uniform
6294  **/
6295 template <class API>
prepare_geometry_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & uniform_definition,const std::string & uniform_use)6296 std::string InteractionUniforms1<API>::prepare_geometry_shader(
6297 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6298 	const std::string& uniform_use)
6299 {
6300 	std::string geometry_shader_source;
6301 
6302 	switch (tested_shader_type)
6303 	{
6304 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6305 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6306 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6307 		break;
6308 
6309 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6310 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6311 		geometry_shader_source = "layout(points)                           in;\n"
6312 								 "layout(triangle_strip, max_vertices = 4) out;\n"
6313 								 "\n"
6314 								 "in  float tes_result[];\n"
6315 								 "out float fs_result;\n"
6316 								 "\n"
6317 								 "void main()\n"
6318 								 "{\n"
6319 								 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
6320 								 "    fs_result    = tes_result[0];\n"
6321 								 "    EmitVertex();\n"
6322 								 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
6323 								 "    fs_result    = tes_result[0];\n"
6324 								 "    EmitVertex();\n"
6325 								 "    gl_Position  = vec4(1, -1, 0, 1);\n"
6326 								 "    fs_result    = tes_result[0];\n"
6327 								 "    EmitVertex();\n"
6328 								 "    gl_Position  = vec4(1, 1, 0, 1);\n"
6329 								 "    fs_result    = tes_result[0];\n"
6330 								 "    EmitVertex();\n"
6331 								 "}\n";
6332 		break;
6333 
6334 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6335 		geometry_shader_source = "layout(points)                           in;\n"
6336 								 "layout(triangle_strip, max_vertices = 4) out;\n"
6337 								 "\n"
6338 								 "out float fs_result;\n"
6339 								 "\n";
6340 
6341 		/* User-defined function definition. */
6342 		geometry_shader_source += uniform_definition;
6343 		geometry_shader_source += "\n\n";
6344 
6345 		/* Main function definition. */
6346 		geometry_shader_source += shader_start;
6347 		geometry_shader_source += uniform_use;
6348 		geometry_shader_source += "\n\n";
6349 		geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
6350 								  "    fs_result    = result;\n"
6351 								  "    EmitVertex();\n"
6352 								  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
6353 								  "    fs_result    = result;\n"
6354 								  "    EmitVertex();\n"
6355 								  "    gl_Position  = vec4(1, -1, 0, 1);\n"
6356 								  "    fs_result    = result;\n"
6357 								  "    EmitVertex();\n"
6358 								  "    gl_Position  = vec4(1, 1, 0, 1);\n"
6359 								  "    fs_result    = result;\n"
6360 								  "    EmitVertex();\n"
6361 								  "}\n";
6362 		break;
6363 
6364 	default:
6365 		TCU_FAIL("Unrecognized shader object type.");
6366 		break;
6367 	}
6368 
6369 	return geometry_shader_source;
6370 }
6371 
6372 /** Prepare shader
6373  *
6374  * @tparam API               Tested API descriptor
6375  *
6376  * @param tested_shader_type The type of shader that is being tested
6377  * @param uniform_definition Definition used to prepare shader
6378  * @param uniform_use        Snippet that use defined uniform
6379  **/
6380 template <class API>
prepare_tess_ctrl_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & uniform_definition,const std::string & uniform_use)6381 std::string InteractionUniforms1<API>::prepare_tess_ctrl_shader(
6382 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6383 	const std::string& uniform_use)
6384 {
6385 	std::string tess_ctrl_shader_source;
6386 
6387 	switch (tested_shader_type)
6388 	{
6389 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6390 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6391 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6392 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6393 		break;
6394 
6395 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6396 		tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
6397 								  "\n"
6398 								  "out float tcs_result[];\n"
6399 								  "\n";
6400 
6401 		/* User-defined function definition. */
6402 		tess_ctrl_shader_source += uniform_definition;
6403 		tess_ctrl_shader_source += "\n\n";
6404 
6405 		/* Main function definition. */
6406 		tess_ctrl_shader_source += shader_start;
6407 		tess_ctrl_shader_source += uniform_use;
6408 		tess_ctrl_shader_source += "\n\n";
6409 		tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
6410 								   "\n"
6411 								   "    gl_TessLevelOuter[0] = 1.0;\n"
6412 								   "    gl_TessLevelOuter[1] = 1.0;\n"
6413 								   "    gl_TessLevelOuter[2] = 1.0;\n"
6414 								   "    gl_TessLevelOuter[3] = 1.0;\n"
6415 								   "    gl_TessLevelInner[0] = 1.0;\n"
6416 								   "    gl_TessLevelInner[1] = 1.0;\n"
6417 								   "}\n";
6418 		break;
6419 
6420 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6421 		tess_ctrl_shader_source = default_tc_shader_source;
6422 		break;
6423 
6424 	default:
6425 		TCU_FAIL("Unrecognized shader object type.");
6426 		break;
6427 	}
6428 
6429 	return tess_ctrl_shader_source;
6430 }
6431 
6432 /** Prepare shader
6433  *
6434  * @tparam API               Tested API descriptor
6435  *
6436  * @param tested_shader_type The type of shader that is being tested
6437  * @param uniform_definition Definition used to prepare shader
6438  * @param uniform_use        Snippet that use defined uniform
6439  **/
6440 template <class API>
prepare_tess_eval_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & uniform_definition,const std::string & uniform_use)6441 std::string InteractionUniforms1<API>::prepare_tess_eval_shader(
6442 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6443 	const std::string& uniform_use)
6444 {
6445 	std::string tess_eval_shader_source;
6446 
6447 	switch (tested_shader_type)
6448 	{
6449 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6450 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6451 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6452 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6453 		break;
6454 
6455 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6456 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
6457 								  "\n"
6458 								  "in  float tcs_result[];\n"
6459 								  "out float tes_result;\n"
6460 								  "\n"
6461 								  "void main()\n"
6462 								  "{\n"
6463 								  "    tes_result = tcs_result[0];\n"
6464 								  "}\n";
6465 		break;
6466 
6467 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6468 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
6469 								  "\n"
6470 								  "out float tes_result;\n"
6471 								  "\n";
6472 
6473 		/* User-defined function definition. */
6474 		tess_eval_shader_source += uniform_definition;
6475 		tess_eval_shader_source += "\n\n";
6476 
6477 		/* Main function definition. */
6478 		tess_eval_shader_source += shader_start;
6479 		tess_eval_shader_source += uniform_use;
6480 		tess_eval_shader_source += "\n\n";
6481 		tess_eval_shader_source += "    tes_result = result;\n"
6482 								   "}\n";
6483 		break;
6484 
6485 	default:
6486 		TCU_FAIL("Unrecognized shader object type.");
6487 		break;
6488 	}
6489 
6490 	return tess_eval_shader_source;
6491 }
6492 
6493 /** Prepare shader
6494  *
6495  * @tparam API               Tested API descriptor
6496  *
6497  * @param tested_shader_type The type of shader that is being tested
6498  * @param uniform_definition Definition used to prepare shader
6499  * @param uniform_use        Snippet that use defined uniform
6500  **/
6501 template <class API>
prepare_vertex_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & uniform_definition,const std::string & uniform_use)6502 std::string InteractionUniforms1<API>::prepare_vertex_shader(
6503 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition,
6504 	const std::string& uniform_use)
6505 {
6506 	std::string vertex_shader_source;
6507 
6508 	switch (tested_shader_type)
6509 	{
6510 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6511 		break;
6512 
6513 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6514 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6515 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
6516 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6517 		vertex_shader_source = default_vertex_shader_source;
6518 		break;
6519 
6520 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
6521 		/* User-defined function definition. */
6522 		vertex_shader_source += uniform_definition;
6523 
6524 		/* Main function definition. */
6525 		vertex_shader_source += shader_start;
6526 		vertex_shader_source += uniform_use;
6527 		vertex_shader_source += "    gl_Position = vec4(result);\n";
6528 		vertex_shader_source += shader_end;
6529 		break;
6530 
6531 	default:
6532 		TCU_FAIL("Unrecognized shader object type.");
6533 		break;
6534 	}
6535 
6536 	return vertex_shader_source;
6537 }
6538 
6539 /* Generates the shader source code for the InteractionUniforms2
6540  * array tests, and attempts to compile each test shader, for both
6541  * vertex and fragment shaders.
6542  *
6543  * @tparam API               Tested API descriptor
6544  *
6545  * @param tested_shader_type The type of shader that is being tested
6546  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6547  */
6548 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)6549 void InteractionUniforms2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
6550 {
6551 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 };
6552 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6553 
6554 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4,
6555 															 VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 };
6556 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6557 
6558 	const std::string array_initializers[] = { "int[2][2][2][2](\n"
6559 											   "    int[2][2][2](\n"
6560 											   "        int[2][2](\n"
6561 											   "            int[2]( 1,  2),\n"
6562 											   "            int[2]( 3,  4)\n"
6563 											   "        ),\n"
6564 											   "        int[2][2](\n"
6565 											   "            int[2]( 5,  6),\n"
6566 											   "            int[2]( 7,  8)\n"
6567 											   "        )\n"
6568 											   "    ),\n"
6569 											   "    int[2][2][2](\n"
6570 											   "        int[2][2](\n"
6571 											   "            int[2](11, 12),\n"
6572 											   "            int[2](13, 14)\n"
6573 											   "        ),\n"
6574 											   "        int[2][2](\n"
6575 											   "            int[2](15, 16),\n"
6576 											   "            int[2](17, 18)\n"
6577 											   "        )\n"
6578 											   "    )\n"
6579 											   ")",
6580 
6581 											   "float[2][2][2][2](\n"
6582 											   "    float[2][2][2](\n"
6583 											   "        float[2][2](\n"
6584 											   "            float[2](1.0, 2.0),\n"
6585 											   "            float[2](3.0, 4.0)),\n"
6586 											   "        float[2][2](\n"
6587 											   "            float[2](5.0, 6.0),\n"
6588 											   "            float[2](7.0, 8.0))),\n"
6589 											   "    float[2][2][2](\n"
6590 											   "        float[2][2](\n"
6591 											   "            float[2](1.1, 2.1),\n"
6592 											   "            float[2](3.1, 4.1)\n"
6593 											   "        ),\n"
6594 											   "        float[2][2](\n"
6595 											   "            float[2](5.1, 6.1),\n"
6596 											   "            float[2](7.1, 8.1)\n"
6597 											   "        )\n"
6598 											   "    )\n"
6599 											   ")",
6600 
6601 											   "mat4[2][2][2][2](\n"
6602 											   "    mat4[2][2][2](\n"
6603 											   "        mat4[2][2](\n"
6604 											   "            mat4[2]( mat4(1),  mat4(2)),\n"
6605 											   "            mat4[2]( mat4(3),  mat4(4))\n"
6606 											   "        ),\n"
6607 											   "        mat4[2][2](\n"
6608 											   "            mat4[2](mat4(5),  mat4(6)),\n"
6609 											   "            mat4[2](mat4(7),  mat4(8))\n"
6610 											   "        )\n"
6611 											   "    ),\n"
6612 											   "    mat4[2][2][2](\n"
6613 											   "        mat4[2][2](\n"
6614 											   "            mat4[2](mat4(9),  mat4(10)),\n"
6615 											   "            mat4[2](mat4(11),  mat4(12))\n"
6616 											   "        ),\n"
6617 											   "        mat4[2][2](\n"
6618 											   "            mat4[2](mat4(13),  mat4(14)),\n"
6619 											   "            mat4[2](mat4(15),  mat4(16))\n"
6620 											   "        )\n"
6621 											   "    )\n"
6622 											   ")",
6623 
6624 											   "double[2][2][2][2](\n"
6625 											   "    double[2][2][2](\n"
6626 											   "        double[2][2](\n"
6627 											   "            double[2](1.0, 2.0),\n"
6628 											   "            double[2](3.0, 4.0)),\n"
6629 											   "        double[2][2](\n"
6630 											   "            double[2](5.0, 6.0),\n"
6631 											   "            double[2](7.0, 8.0))),\n"
6632 											   "    double[2][2][2](\n"
6633 											   "        double[2][2](\n"
6634 											   "            double[2](1.1, 2.1),\n"
6635 											   "            double[2](3.1, 4.1)\n"
6636 											   "        ),\n"
6637 											   "        double[2][2](\n"
6638 											   "            double[2](5.1, 6.1),\n"
6639 											   "            double[2](7.1, 8.1)\n"
6640 											   "        )\n"
6641 											   "    )\n"
6642 											   ")",
6643 
6644 											   "dmat4[2][2][2][2](\n"
6645 											   "    dmat4[2][2][2](\n"
6646 											   "        dmat4[2][2](\n"
6647 											   "            dmat4[2]( dmat4(1),  dmat4(2)),\n"
6648 											   "            dmat4[2]( dmat4(3),  dmat4(4))\n"
6649 											   "        ),\n"
6650 											   "        dmat4[2][2](\n"
6651 											   "            dmat4[2](dmat4(5),  dmat4(6)),\n"
6652 											   "            dmat4[2](dmat4(7),  dmat4(8))\n"
6653 											   "        )\n"
6654 											   "    ),\n"
6655 											   "    dmat4[2][2][2](\n"
6656 											   "        dmat4[2][2](\n"
6657 											   "            dmat4[2](dmat4(9),   dmat4(10)),\n"
6658 											   "            dmat4[2](dmat4(11),  dmat4(12))\n"
6659 											   "        ),\n"
6660 											   "        dmat4[2][2](\n"
6661 											   "            dmat4[2](dmat4(13),  dmat4(14)),\n"
6662 											   "            dmat4[2](dmat4(15),  dmat4(16))\n"
6663 											   "        )\n"
6664 											   "    )\n"
6665 											   ")" };
6666 
6667 	const glcts::test_var_type* var_types_set = var_types_set_es;
6668 	size_t						num_var_types = num_var_types_es;
6669 
6670 	if (API::USE_DOUBLE)
6671 	{
6672 		var_types_set = var_types_set_gl;
6673 		num_var_types = num_var_types_gl;
6674 	}
6675 
6676 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6677 	{
6678 		_supported_variable_types_map_const_iterator var_iterator =
6679 			supported_variable_types_map.find(var_types_set[var_type_index]);
6680 
6681 		if (var_iterator != supported_variable_types_map.end())
6682 		{
6683 			std::string base_variable_string;
6684 
6685 			for (int initialiser_selector = 1; initialiser_selector >= 0; initialiser_selector--)
6686 			{
6687 				// We normally do all 16 possible permutations of [4][4][4][4] items (15..0).
6688 				// However, in this case we will skip the case that will work,
6689 				// so we'll merely process permutations 14..0
6690 				for (int permutation_index = 14; permutation_index >= 0; permutation_index--)
6691 				{
6692 					base_variable_string =
6693 						"uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " x";
6694 
6695 					// for all 4 possible sub_script entries
6696 					for (int sub_script_entry_index = 3; sub_script_entry_index >= 0; sub_script_entry_index--)
6697 					{
6698 						if (permutation_index & (1 << sub_script_entry_index))
6699 						{
6700 							// In this case, we'll use a valid sub_script
6701 							base_variable_string += "[2]";
6702 						}
6703 						else
6704 						{
6705 							// In this case, we'll use an invalid sub_script
6706 							base_variable_string += "[]";
6707 						}
6708 					}
6709 
6710 					if (initialiser_selector == 0)
6711 					{
6712 						// We'll use an initialiser
6713 						base_variable_string += " = " + array_initializers[var_type_index];
6714 					}
6715 
6716 					base_variable_string += ";\n\n";
6717 
6718 					std::string shader_source = base_variable_string + shader_start;
6719 
6720 					/* End main */
6721 					DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
6722 
6723 					/* Execute test:
6724 					 *
6725 					 * This will succeed in case of allowed unsized
6726 					 * declarations and when at least one of these is
6727 					 * true:
6728 					 *   1. There is an initialiser.
6729 					 *   2. Only the outermost dimension is unsized,
6730 					 *      as in [][2][2][2].
6731 					 */
6732 					EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION &&
6733 											(initialiser_selector == 0 || permutation_index == 7),
6734 										tested_shader_type, shader_source);
6735 				} /* for (int permutation_index = 14; ...) */
6736 			}	 /* for (int initialiser_selector  = 1; ...) */
6737 		}		  /* if var_type iterator found */
6738 		else
6739 		{
6740 			TCU_FAIL("Type not found.");
6741 		}
6742 	} /* for (int var_type_index = 0; ...) */
6743 }
6744 
6745 /* Generates the shader source code for the InteractionUniformBuffers1
6746  * array tests, and attempts to compile each test shader, for both
6747  * vertex and fragment shaders.
6748  *
6749  * @tparam API               Tested API descriptor
6750  *
6751  * @param tested_shader_type The type of shader that is being tested
6752  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6753  */
6754 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)6755 void InteractionUniformBuffers1<API>::test_shader_compilation(
6756 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
6757 {
6758 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
6759 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6760 
6761 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
6762 															 VAR_TYPE_DOUBLE };
6763 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6764 
6765 	const glcts::test_var_type* var_types_set = var_types_set_es;
6766 	size_t						num_var_types = num_var_types_es;
6767 
6768 	if (API::USE_DOUBLE)
6769 	{
6770 		var_types_set = var_types_set_gl;
6771 		num_var_types = num_var_types_gl;
6772 	}
6773 
6774 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6775 	{
6776 		_supported_variable_types_map_const_iterator var_iterator =
6777 			supported_variable_types_map.find(var_types_set[var_type_index]);
6778 
6779 		if (var_iterator != supported_variable_types_map.end())
6780 		{
6781 			std::string shader_source;
6782 
6783 			shader_source += "uniform uBlocka {\n";
6784 			shader_source += "    " + var_iterator->second.type + " x[1][1][1][1][1][1];\n";
6785 			shader_source += "};\n\n";
6786 			shader_source += shader_start;
6787 
6788 			/* End main */
6789 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
6790 
6791 			/* Execute test */
6792 			EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
6793 		} /* if var_type iterator found */
6794 		else
6795 		{
6796 			TCU_FAIL("Type not found.");
6797 		}
6798 	}
6799 }
6800 
6801 /* Generates the shader source code for the InteractionUniformBuffers2
6802  * array tests, and attempts to compile each test shader, for both
6803  * vertex and fragment shaders.
6804  *
6805  * @tparam API               Tested API descriptor
6806  *
6807  * @param tested_shader_type The type of shader that is being tested
6808  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
6809  */
6810 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)6811 void InteractionUniformBuffers2<API>::test_shader_compilation(
6812 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
6813 {
6814 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
6815 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
6816 
6817 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
6818 															 VAR_TYPE_DOUBLE };
6819 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
6820 
6821 	const glw::Functions&		gl			  = this->context_id.getRenderContext().getFunctions();
6822 	const glcts::test_var_type* var_types_set = var_types_set_es;
6823 	size_t						num_var_types = num_var_types_es;
6824 
6825 	if (API::USE_DOUBLE)
6826 	{
6827 		var_types_set = var_types_set_gl;
6828 		num_var_types = num_var_types_gl;
6829 	}
6830 
6831 	/* Iterate through float / int / uint values. */
6832 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
6833 	{
6834 		_supported_variable_types_map_const_iterator var_iterator =
6835 			supported_variable_types_map.find(var_types_set[var_type_index]);
6836 
6837 		if (var_iterator != supported_variable_types_map.end())
6838 		{
6839 			std::string uniform_definition;
6840 			std::string uniform_use;
6841 
6842 			uniform_definition += "layout (std140) uniform uniform_block_name\n"
6843 								  "{\n";
6844 			uniform_definition += "    ";
6845 			uniform_definition += var_iterator->second.type;
6846 			uniform_definition += " my_uniform_1[1][1][1][1];\n"
6847 								  "};\n";
6848 
6849 			uniform_use = "    float result = float(my_uniform_1[0][0][0][0]);\n";
6850 
6851 			if (API::USE_ALL_SHADER_STAGES)
6852 			{
6853 				const std::string& compute_shader_source =
6854 					this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use);
6855 				const std::string& fragment_shader_source =
6856 					this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6857 				const std::string& geometry_shader_source =
6858 					this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use);
6859 				const std::string& tess_ctrl_shader_source =
6860 					this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use);
6861 				const std::string& tess_eval_shader_source =
6862 					this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use);
6863 				const std::string& vertex_shader_source =
6864 					this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6865 
6866 				switch (tested_shader_type)
6867 				{
6868 				case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
6869 				case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
6870 					this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6871 					break;
6872 
6873 				case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
6874 				case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
6875 				case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
6876 				case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
6877 					this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
6878 												geometry_shader_source, fragment_shader_source, compute_shader_source,
6879 												false, false);
6880 					break;
6881 
6882 				default:
6883 					TCU_FAIL("Invalid enum");
6884 					break;
6885 				}
6886 			}
6887 			else
6888 			{
6889 				const std::string& fragment_shader_source =
6890 					this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
6891 				const std::string& vertex_shader_source =
6892 					this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
6893 
6894 				this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
6895 			}
6896 
6897 			glw::GLuint buffer_object_id	   = 0;
6898 			glw::GLint  my_uniform_block_index = GL_INVALID_INDEX;
6899 
6900 			gl.useProgram(this->program_object_id);
6901 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
6902 
6903 			my_uniform_block_index = gl.getUniformBlockIndex(this->program_object_id, "uniform_block_name");
6904 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex() failed.");
6905 
6906 			if ((unsigned)my_uniform_block_index == GL_INVALID_INDEX)
6907 			{
6908 				TCU_FAIL("Uniform block not found or is considered as not active.");
6909 			}
6910 
6911 			gl.genBuffers(1, &buffer_object_id);
6912 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed.");
6913 
6914 			gl.bindBuffer(GL_UNIFORM_BUFFER, buffer_object_id);
6915 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed.");
6916 
6917 			switch (var_type_index)
6918 			{
6919 			case 0: //float type of uniform is considered
6920 			{
6921 				glw::GLfloat buffer_data[] = { 0.0f, 1.0f, 2.0f,  3.0f,  4.0f,  5.0f,  6.0f,  7.0f,
6922 											   8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f };
6923 
6924 				gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6925 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6926 
6927 				break;
6928 			}		/* float case */
6929 			case 1: //int type of uniform is considered
6930 			{
6931 
6932 				glw::GLint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
6933 
6934 				gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6935 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6936 
6937 				break;
6938 			}		/* int case */
6939 			case 2: //uint type of uniform is considered
6940 			{
6941 				glw::GLuint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
6942 
6943 				gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6944 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6945 
6946 				break;
6947 			}		/* uint case */
6948 			case 3: //double type of uniform is considered
6949 			{
6950 				glw::GLdouble buffer_data[] = { 0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,
6951 												8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 };
6952 
6953 				gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
6954 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
6955 
6956 				break;
6957 			} /* double case */
6958 			default:
6959 			{
6960 				TCU_FAIL("Invalid variable-type index.");
6961 
6962 				break;
6963 			}
6964 			} /* switch (var_type_index) */
6965 
6966 			gl.uniformBlockBinding(this->program_object_id, my_uniform_block_index, 0);
6967 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding() failed.");
6968 
6969 			gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, buffer_object_id);
6970 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed.");
6971 
6972 			if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type)
6973 			{
6974 				execute_draw_test(tested_shader_type);
6975 			}
6976 			else
6977 			{
6978 				execute_dispatch_test();
6979 			}
6980 
6981 			/* Deallocate any resources used. */
6982 			gl.deleteBuffers(1, &buffer_object_id);
6983 			this->delete_objects();
6984 		} /* if var_type iterator found */
6985 		else
6986 		{
6987 			TCU_FAIL("Type not found.");
6988 		}
6989 	} /* for (int var_type_index = 0; ...) */
6990 }
6991 
6992 /** Executes test for compute program
6993  *
6994  * @tparam API Tested API descriptor
6995  **/
6996 template <class API>
execute_dispatch_test()6997 void InteractionUniformBuffers2<API>::execute_dispatch_test()
6998 {
6999 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7000 
7001 	gl.dispatchCompute(1, 1, 1);
7002 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7003 }
7004 
7005 /** Executes test for draw program
7006  *
7007  * @tparam API               Tested API descriptor
7008  *
7009  * @param tested_shader_type The type of shader that is being tested
7010  **/
7011 template <class API>
execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type)7012 void InteractionUniformBuffers2<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type)
7013 {
7014 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7015 
7016 	glw::GLuint vao_id = 0;
7017 
7018 	gl.genVertexArrays(1, &vao_id);
7019 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
7020 
7021 	gl.bindVertexArray(vao_id);
7022 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
7023 
7024 	switch (tested_shader_type)
7025 	{
7026 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7027 	case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
7028 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7029 		gl.drawArrays(GL_POINTS, 0, 1);
7030 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7031 		break;
7032 
7033 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
7034 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7035 		/* Tesselation patch set up */
7036 		gl.patchParameteri(GL_PATCH_VERTICES, 1);
7037 		GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
7038 
7039 		gl.drawArrays(GL_PATCHES, 0, 1);
7040 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7041 		break;
7042 
7043 	default:
7044 		TCU_FAIL("Invalid enum");
7045 		break;
7046 	}
7047 
7048 	gl.deleteVertexArrays(1, &vao_id);
7049 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() failed.");
7050 }
7051 
7052 /* Generates the shader source code for the InteractionUniformBuffers3
7053  * array tests, and attempts to compile each test shader, for both
7054  * vertex and fragment shaders.
7055  *
7056  * @tparam API               Tested API descriptor
7057  *
7058  * @param tested_shader_type The type of shader that is being tested
7059  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7060  */
7061 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)7062 void InteractionUniformBuffers3<API>::test_shader_compilation(
7063 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
7064 {
7065 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7066 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7067 
7068 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7069 															 VAR_TYPE_DOUBLE };
7070 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7071 
7072 	const std::string invalid_size_declarations[] = { "[2][2][2][]", "[2][2][][2]", "[2][][2][2]", "[][2][2][2]",
7073 													  "[2][2][][]",  "[2][][2][]",  "[][2][2][]",  "[2][][][2]",
7074 													  "[][2][][2]",  "[][][2][2]",  "[2][][][]",   "[][2][][]",
7075 													  "[][][2][]",   "[][][][2]",   "[][][][]" };
7076 
7077 	const std::string array_initializers[] = { "float[2][2][2][2](float[2][2][2](float[2][2](float[2](1.0, 2.0),"
7078 											   "float[2](3.0, 4.0)),"
7079 											   "float[2][2](float[2](5.0, 6.0),"
7080 											   "float[2](7.0, 8.0))),"
7081 											   "float[2][2][2](float[2][2](float[2](1.1, 2.1),"
7082 											   "float[2](3.1, 4.1)),"
7083 											   "float[2][2](float[2](5.1, 6.1),"
7084 											   "float[2](7.1, 8.1))));\n",
7085 
7086 											   "int[2][2][2][2](int[2][2][2](int[2][2](int[2]( 1,  2),"
7087 											   "int[2]( 3,  4)),"
7088 											   "int[2][2](int[2]( 5,  6),"
7089 											   "int[2]( 7,  8))),"
7090 											   "int[2][2][2](int[2][2](int[2](11, 12),"
7091 											   "int[2](13, 14)),"
7092 											   "int[2][2](int[2](15, 16),"
7093 											   "int[2](17, 18))));\n",
7094 
7095 											   "uint[2][2][2][2](uint[2][2][2](uint[2][2](uint[2]( 1u,  2u),"
7096 											   "uint[2]( 3u,  4u)),"
7097 											   "uint[2][2](uint[2]( 5u,  6u),"
7098 											   "uint[2]( 7u,  8u))),"
7099 											   "uint[2][2][2](uint[2][2](uint[2](11u, 12u),"
7100 											   "uint[2](13u, 14u)),"
7101 											   "uint[2][2](uint[2](15u, 16u),"
7102 											   "uint[2](17u, 18u))));\n",
7103 
7104 											   "double[2][2][2][2](double[2][2][2](double[2][2](double[2](1.0, 2.0),"
7105 											   "double[2](3.0, 4.0)),"
7106 											   "double[2][2](double[2](5.0, 6.0),"
7107 											   "double[2](7.0, 8.0))),"
7108 											   "double[2][2][2](double[2][2](double[2](1.1, 2.1),"
7109 											   "double[2](3.1, 4.1)),"
7110 											   "double[2][2](double[2](5.1, 6.1),"
7111 											   "double[2](7.1, 8.1))));\n" };
7112 	const glcts::test_var_type* var_types_set = var_types_set_es;
7113 	size_t						num_var_types = num_var_types_es;
7114 
7115 	if (API::USE_DOUBLE)
7116 	{
7117 		var_types_set = var_types_set_gl;
7118 		num_var_types = num_var_types_gl;
7119 	}
7120 
7121 	/* Iterate through float/ int/ uint types.
7122 	 * Case: without initializer.
7123 	 */
7124 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7125 	{
7126 		_supported_variable_types_map_const_iterator var_iterator =
7127 			supported_variable_types_map.find(var_types_set[var_type_index]);
7128 
7129 		if (var_iterator != supported_variable_types_map.end())
7130 		{
7131 			for (size_t invalid_size_declarations_index = 0;
7132 				 invalid_size_declarations_index <
7133 				 sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7134 				 invalid_size_declarations_index++)
7135 			{
7136 				std::string shader_source;
7137 
7138 				shader_source = "layout (std140) uniform MyUniform {\n";
7139 				shader_source += "    " + var_iterator->second.type +
7140 								 invalid_size_declarations[invalid_size_declarations_index] + " my_variable;\n";
7141 				shader_source += "};\n\n";
7142 				shader_source += shader_start;
7143 
7144 				/* End main */
7145 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7146 
7147 				/* Execute test */
7148 				EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && invalid_size_declarations_index == 3,
7149 									tested_shader_type, shader_source);
7150 			} /* for (int invalid_size_declarations_index = 0; ...) */
7151 		}
7152 		else
7153 		{
7154 			TCU_FAIL("Type not found.");
7155 		}
7156 	} /* for (int var_type_index = 0; ...) */
7157 
7158 	/* Iterate through float/ int/ uint types.
7159 	 * Case: with initializer.
7160 	 */
7161 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7162 	{
7163 		_supported_variable_types_map_const_iterator var_iterator =
7164 			supported_variable_types_map.find(var_types_set[var_type_index]);
7165 
7166 		if (var_iterator != supported_variable_types_map.end())
7167 		{
7168 			for (size_t invalid_size_declarations_index = 0;
7169 				 invalid_size_declarations_index <
7170 				 sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7171 				 invalid_size_declarations_index++)
7172 			{
7173 				std::string shader_source;
7174 
7175 				shader_source = "layout (std140) uniform MyUniform {\n";
7176 				shader_source += "    " + var_iterator->second.type +
7177 								 invalid_size_declarations[invalid_size_declarations_index] +
7178 								 " my_variable = " + array_initializers[var_type_index];
7179 				shader_source += "};\n\n";
7180 				shader_source += shader_start;
7181 
7182 				/* End main */
7183 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7184 
7185 				/* Execute test */
7186 				this->execute_negative_test(tested_shader_type, shader_source);
7187 			} /* for (int invalid_size_declarations_index = 0; ...) */
7188 		}	 /* if var_type iterator found */
7189 		else
7190 		{
7191 			TCU_FAIL("Type not found.");
7192 		}
7193 	} /* for (int var_type_index = 0; ...) */
7194 }
7195 
7196 /* Generates the shader source code for the InteractionStorageBuffers1
7197  * array tests, and attempts to compile each test shader, for both
7198  * vertex and fragment shaders.
7199  *
7200  * @tparam API               Tested API descriptor
7201  *
7202  * @param tested_shader_type The type of shader that is being tested
7203  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7204  */
7205 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)7206 void InteractionStorageBuffers1<API>::test_shader_compilation(
7207 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
7208 {
7209 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7210 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7211 
7212 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7213 															 VAR_TYPE_DOUBLE };
7214 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7215 
7216 	const glcts::test_var_type* var_types_set = var_types_set_es;
7217 	size_t						num_var_types = num_var_types_es;
7218 
7219 	if (API::USE_DOUBLE)
7220 	{
7221 		var_types_set = var_types_set_gl;
7222 		num_var_types = num_var_types_gl;
7223 	}
7224 
7225 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7226 	{
7227 		_supported_variable_types_map_const_iterator var_iterator =
7228 			supported_variable_types_map.find(var_types_set[var_type_index]);
7229 
7230 		if (var_iterator != supported_variable_types_map.end())
7231 		{
7232 			std::string shader_source;
7233 
7234 			shader_source += "buffer uBlocka {\n";
7235 			shader_source += "    " + var_iterator->second.type + " x[1][1][1][1][1][1];\n";
7236 			shader_source += "};\n\n";
7237 			shader_source += shader_start;
7238 
7239 			/* End main */
7240 			DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7241 
7242 			/* Execute test */
7243 			EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false);
7244 		} /* if var_type iterator found */
7245 		else
7246 		{
7247 			TCU_FAIL("Type not found.");
7248 		}
7249 	}
7250 }
7251 
7252 /* Generates the shader source code for the InteractionUniformBuffers2
7253  * array tests, and attempts to compile each test shader, for both
7254  * vertex and fragment shaders.
7255  *
7256  * @tparam API               Tested API descriptor
7257  *
7258  * @param tested_shader_type The type of shader that is being tested
7259  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7260  */
7261 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)7262 void InteractionStorageBuffers2<API>::test_shader_compilation(
7263 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
7264 {
7265 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7266 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7267 
7268 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7269 															 VAR_TYPE_DOUBLE };
7270 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7271 
7272 	const glw::Functions&		gl			  = this->context_id.getRenderContext().getFunctions();
7273 	const glcts::test_var_type* var_types_set = var_types_set_es;
7274 	size_t						num_var_types = num_var_types_es;
7275 
7276 	if (API::USE_DOUBLE)
7277 	{
7278 		var_types_set = var_types_set_gl;
7279 		num_var_types = num_var_types_gl;
7280 	}
7281 
7282 	/* Iterate through float / int / uint values. */
7283 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7284 	{
7285 		_supported_variable_types_map_const_iterator var_iterator =
7286 			supported_variable_types_map.find(var_types_set[var_type_index]);
7287 
7288 		if (var_iterator != supported_variable_types_map.end())
7289 		{
7290 			std::string uniform_definition;
7291 			std::string uniform_use;
7292 
7293 			uniform_definition += "layout (std140) buffer storage_block_name\n"
7294 								  "{\n";
7295 			uniform_definition += "    ";
7296 			uniform_definition += var_iterator->second.type;
7297 			uniform_definition += " my_storage_1[1][1][1][1];\n"
7298 								  "};\n";
7299 
7300 			uniform_use = "    float result = float(my_storage_1[0][0][0][0]);\n";
7301 
7302 			if (API::USE_ALL_SHADER_STAGES)
7303 			{
7304 				const std::string& compute_shader_source =
7305 					this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use);
7306 				const std::string& fragment_shader_source =
7307 					this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
7308 				const std::string& geometry_shader_source =
7309 					this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use);
7310 				const std::string& tess_ctrl_shader_source =
7311 					this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use);
7312 				const std::string& tess_eval_shader_source =
7313 					this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use);
7314 				const std::string& vertex_shader_source =
7315 					this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
7316 
7317 				switch (tested_shader_type)
7318 				{
7319 				case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
7320 				case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7321 					this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
7322 					break;
7323 
7324 				case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7325 				case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7326 				case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
7327 				case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7328 					this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
7329 												geometry_shader_source, fragment_shader_source, compute_shader_source,
7330 												false, false);
7331 					break;
7332 
7333 				default:
7334 					TCU_FAIL("Invalid enum");
7335 					break;
7336 				}
7337 			}
7338 			else
7339 			{
7340 				const std::string& fragment_shader_source =
7341 					this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use);
7342 				const std::string& vertex_shader_source =
7343 					this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use);
7344 
7345 				this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
7346 			}
7347 
7348 			glw::GLuint buffer_object_id	   = 0;
7349 			glw::GLint  my_storage_block_index = GL_INVALID_INDEX;
7350 
7351 			gl.useProgram(this->program_object_id);
7352 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
7353 
7354 			my_storage_block_index =
7355 				gl.getProgramResourceIndex(this->program_object_id, GL_SHADER_STORAGE_BLOCK, "storage_block_name");
7356 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() failed.");
7357 
7358 			if ((unsigned)my_storage_block_index == GL_INVALID_INDEX)
7359 			{
7360 				TCU_FAIL("Uniform block not found or is considered as not active.");
7361 			}
7362 
7363 			gl.genBuffers(1, &buffer_object_id);
7364 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed.");
7365 
7366 			gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_object_id);
7367 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed.");
7368 
7369 			switch (var_type_index)
7370 			{
7371 			case 0: //float type of uniform is considered
7372 			{
7373 				glw::GLfloat buffer_data[] = { 0.0f, 1.0f, 2.0f,  3.0f,  4.0f,  5.0f,  6.0f,  7.0f,
7374 											   8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f };
7375 
7376 				gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7377 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7378 
7379 				break;
7380 			}		/* float case */
7381 			case 1: //int type of uniform is considered
7382 			{
7383 
7384 				glw::GLint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
7385 
7386 				gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7387 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7388 
7389 				break;
7390 			}		/* int case */
7391 			case 2: //uint type of uniform is considered
7392 			{
7393 				glw::GLuint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
7394 
7395 				gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7396 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7397 
7398 				break;
7399 			}		/* uint case */
7400 			case 3: //double type of uniform is considered
7401 			{
7402 				glw::GLdouble buffer_data[] = { 0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,
7403 												8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 };
7404 
7405 				gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW);
7406 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
7407 
7408 				break;
7409 			} /* double case */
7410 			default:
7411 			{
7412 				TCU_FAIL("Invalid variable-type index.");
7413 
7414 				break;
7415 			}
7416 			} /* switch (var_type_index) */
7417 
7418 			gl.shaderStorageBlockBinding(this->program_object_id, my_storage_block_index, 0);
7419 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding() failed.");
7420 
7421 			gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer_object_id);
7422 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed.");
7423 
7424 			if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type)
7425 			{
7426 				execute_draw_test(tested_shader_type);
7427 			}
7428 			else
7429 			{
7430 				execute_dispatch_test();
7431 			}
7432 
7433 			/* Deallocate any resources used. */
7434 			gl.deleteBuffers(1, &buffer_object_id);
7435 			this->delete_objects();
7436 		} /* if var_type iterator found */
7437 		else
7438 		{
7439 			TCU_FAIL("Type not found.");
7440 		}
7441 	} /* for (int var_type_index = 0; ...) */
7442 }
7443 
7444 /** Executes test for compute program
7445  *
7446  * @tparam API               Tested API descriptor
7447  **/
7448 template <class API>
execute_dispatch_test()7449 void InteractionStorageBuffers2<API>::execute_dispatch_test()
7450 {
7451 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7452 
7453 	gl.dispatchCompute(1, 1, 1);
7454 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7455 }
7456 
7457 /** Executes test for draw program
7458  *
7459  * @tparam API               Tested API descriptor
7460  *
7461  * @param tested_shader_type The type of shader that is being tested
7462  **/
7463 template <class API>
execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type)7464 void InteractionStorageBuffers2<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type)
7465 {
7466 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
7467 
7468 	glw::GLuint vao_id = 0;
7469 
7470 	gl.genVertexArrays(1, &vao_id);
7471 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
7472 
7473 	gl.bindVertexArray(vao_id);
7474 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
7475 
7476 	switch (tested_shader_type)
7477 	{
7478 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7479 	case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
7480 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7481 		gl.drawArrays(GL_POINTS, 0, 1);
7482 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7483 		break;
7484 
7485 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
7486 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7487 		/* Tesselation patch set up */
7488 		gl.patchParameteri(GL_PATCH_VERTICES, 1);
7489 		GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
7490 
7491 		gl.drawArrays(GL_PATCHES, 0, 1);
7492 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
7493 		break;
7494 
7495 	default:
7496 		TCU_FAIL("Invalid enum");
7497 		break;
7498 	}
7499 
7500 	gl.deleteVertexArrays(1, &vao_id);
7501 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() failed.");
7502 }
7503 
7504 /* Generates the shader source code for the InteractionUniformBuffers3
7505  * array tests, and attempts to compile each test shader, for both
7506  * vertex and fragment shaders.
7507  *
7508  * @tparam API               Tested API descriptor
7509  *
7510  * @param tested_shader_type The type of shader that is being tested
7511  *                           (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE).
7512  */
7513 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)7514 void InteractionStorageBuffers3<API>::test_shader_compilation(
7515 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
7516 {
7517 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT };
7518 	static const size_t				  num_var_types_es   = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
7519 
7520 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT,
7521 															 VAR_TYPE_DOUBLE };
7522 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
7523 
7524 	const std::string invalid_size_declarations[] = { "[2][2][2][]", "[2][2][][2]", "[2][][2][2]", "[][2][2][2]",
7525 													  "[2][2][][]",  "[2][][2][]",  "[][2][2][]",  "[2][][][2]",
7526 													  "[][2][][2]",  "[][][2][2]",  "[2][][][]",   "[][2][][]",
7527 													  "[][][2][]",   "[][][][2]",   "[][][][]" };
7528 	const std::string array_initializers[] = { "float[2][2][2][2](float[2][2][2](float[2][2](float[2](1.0, 2.0),"
7529 											   "float[2](3.0, 4.0)),"
7530 											   "float[2][2](float[2](5.0, 6.0),"
7531 											   "float[2](7.0, 8.0))),"
7532 											   "float[2][2][2](float[2][2](float[2](1.1, 2.1),"
7533 											   "float[2](3.1, 4.1)),"
7534 											   "float[2][2](float[2](5.1, 6.1),"
7535 											   "float[2](7.1, 8.1))));\n",
7536 
7537 											   "int[2][2][2][2](int[2][2][2](int[2][2](int[2]( 1,  2),"
7538 											   "int[2]( 3,  4)),"
7539 											   "int[2][2](int[2]( 5,  6),"
7540 											   "int[2]( 7,  8))),"
7541 											   "int[2][2][2](int[2][2](int[2](11, 12),"
7542 											   "int[2](13, 14)),"
7543 											   "int[2][2](int[2](15, 16),"
7544 											   "int[2](17, 18))));\n",
7545 
7546 											   "uint[2][2][2][2](uint[2][2][2](uint[2][2](uint[2]( 1u,  2u),"
7547 											   "uint[2]( 3u,  4u)),"
7548 											   "uint[2][2](uint[2]( 5u,  6u),"
7549 											   "uint[2]( 7u,  8u))),"
7550 											   "uint[2][2][2](uint[2][2](uint[2](11u, 12u),"
7551 											   "uint[2](13u, 14u)),"
7552 											   "uint[2][2](uint[2](15u, 16u),"
7553 											   "uint[2](17u, 18u))));\n",
7554 
7555 											   "double[2][2][2][2](double[2][2][2](double[2][2](double[2](1.0, 2.0),"
7556 											   "double[2](3.0, 4.0)),"
7557 											   "double[2][2](double[2](5.0, 6.0),"
7558 											   "double[2](7.0, 8.0))),"
7559 											   "double[2][2][2](double[2][2](double[2](1.1, 2.1),"
7560 											   "double[2](3.1, 4.1)),"
7561 											   "double[2][2](double[2](5.1, 6.1),"
7562 											   "double[2](7.1, 8.1))));\n" };
7563 	const glcts::test_var_type* var_types_set = var_types_set_es;
7564 	size_t						num_var_types = num_var_types_es;
7565 
7566 	if (API::USE_DOUBLE)
7567 	{
7568 		var_types_set = var_types_set_gl;
7569 		num_var_types = num_var_types_gl;
7570 	}
7571 
7572 	/* Iterate through float/ int/ uint types.
7573 	 * Case: without initializer.
7574 	 */
7575 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7576 	{
7577 		_supported_variable_types_map_const_iterator var_iterator =
7578 			supported_variable_types_map.find(var_types_set[var_type_index]);
7579 
7580 		if (var_iterator != supported_variable_types_map.end())
7581 		{
7582 			for (size_t invalid_size_declarations_index = 0;
7583 				 invalid_size_declarations_index <
7584 				 sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7585 				 invalid_size_declarations_index++)
7586 			{
7587 				std::string shader_source;
7588 
7589 				shader_source = "layout (std140) buffer MyStorage {\n";
7590 				shader_source += "    " + var_iterator->second.type +
7591 								 invalid_size_declarations[invalid_size_declarations_index] + " my_variable;\n";
7592 				shader_source += "};\n\n";
7593 				shader_source += shader_start;
7594 
7595 				/* End main */
7596 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7597 
7598 				/* Execute test */
7599 				EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && invalid_size_declarations_index == 3,
7600 									tested_shader_type, shader_source);
7601 			} /* for (int invalid_size_declarations_index = 0; ...) */
7602 		}
7603 		else
7604 		{
7605 			TCU_FAIL("Type not found.");
7606 		}
7607 	} /* for (int var_type_index = 0; ...) */
7608 
7609 	/* Iterate through float/ int/ uint types.
7610 	 * Case: with initializer.
7611 	 */
7612 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
7613 	{
7614 		_supported_variable_types_map_const_iterator var_iterator =
7615 			supported_variable_types_map.find(var_types_set[var_type_index]);
7616 
7617 		if (var_iterator != supported_variable_types_map.end())
7618 		{
7619 			for (size_t invalid_size_declarations_index = 0;
7620 				 invalid_size_declarations_index <
7621 				 sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]);
7622 				 invalid_size_declarations_index++)
7623 			{
7624 				std::string shader_source;
7625 
7626 				shader_source = "layout (std140) buffer MyStorage {\n";
7627 				shader_source += "    " + var_iterator->second.type +
7628 								 invalid_size_declarations[invalid_size_declarations_index] +
7629 								 " my_variable = " + array_initializers[var_type_index];
7630 				shader_source += "};\n\n";
7631 				shader_source += shader_start;
7632 
7633 				/* End main */
7634 				DEFAULT_MAIN_ENDING(tested_shader_type, shader_source);
7635 
7636 				/* Execute test */
7637 				this->execute_negative_test(tested_shader_type, shader_source);
7638 			} /* for (int invalid_size_declarations_index = 0; ...) */
7639 		}	 /* if var_type iterator found */
7640 		else
7641 		{
7642 			TCU_FAIL("Type not found.");
7643 		}
7644 	} /* for (int var_type_index = 0; ...) */
7645 }
7646 
7647 /* Generates the shader source code for the InteractionInterfaceArrays1
7648  * array test, and attempts to compile the test shader.
7649  *
7650  * @tparam API               Tested API descriptor
7651  *
7652  * @param tested_shader_type The type of shader that is being tested.
7653  */
7654 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)7655 void InteractionInterfaceArrays1<API>::test_shader_compilation(
7656 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
7657 {
7658 	/* Shader source with invalid buffer (buffer cannot be of arrays of arrays type). */
7659 	const std::string invalid_buffer_shader_source = "layout(std140) buffer MyBuffer\n"
7660 													 "{\n"
7661 													 "    float f;\n"
7662 													 "    int   i;\n"
7663 													 "    uint  ui;\n"
7664 													 "} myBuffers[2][2];\n\n"
7665 													 "void main()\n"
7666 													 "{\n";
7667 
7668 	/* Verify that buffer arrays of arrays type is rejected. */
7669 	{
7670 		std::string source = invalid_buffer_shader_source;
7671 
7672 		DEFAULT_MAIN_ENDING(tested_shader_type, source);
7673 
7674 		EXECUTE_SHADER_TEST(API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS, tested_shader_type, source);
7675 	}
7676 }
7677 
7678 /* Generates the shader source code for the InteractionInterfaceArrays2
7679  * array test, and attempts to compile the test shader.
7680  *
7681  * @tparam API              Tested API descriptor
7682  *
7683  * @param input_shader_type The type of shader that is being tested.
7684  */
7685 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType input_shader_type)7686 void InteractionInterfaceArrays2<API>::test_shader_compilation(
7687 	typename TestCaseBase<API>::TestShaderType input_shader_type)
7688 {
7689 	/* Shader source with invalid input (input cannot be of arrays of arrays type). */
7690 	const std::string input_variable_shader_source[] = { "in  float inout_variable", "[2][2];\n"
7691 																					 "out float result",
7692 														 ";\n\n"
7693 														 "void main()\n"
7694 														 "{\n"
7695 														 "    result",
7696 														 " = inout_variable", "[0][0];\n" };
7697 	/* Shader source with invalid output (output cannot be of arrays of arrays type). */
7698 	const std::string output_variable_shader_source[] = { "out float inout_variable",
7699 														  "[2][2];\n\n"
7700 														  "void main()\n"
7701 														  "{\n"
7702 														  "    inout_variable",
7703 														  "[0][0] = 0.0;\n"
7704 														  "    inout_variable",
7705 														  "[0][1] = 1.0;\n"
7706 														  "    inout_variable",
7707 														  "[1][0] = 2.0;\n"
7708 														  "    inout_variable",
7709 														  "[1][1] = 3.0;\n" };
7710 
7711 	const typename TestCaseBase<API>::TestShaderType& output_shader_type =
7712 		this->get_output_shader_type(input_shader_type);
7713 	std::string input_source;
7714 	std::string output_source;
7715 
7716 	this->prepare_sources(input_shader_type, output_shader_type, input_variable_shader_source,
7717 						  output_variable_shader_source, input_source, output_source);
7718 
7719 	/* Verify that INPUTs and OUTPUTs arrays of arrays type is rejected. */
7720 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type)
7721 	{
7722 		if (API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS)
7723 		{
7724 
7725 			if (API::USE_ALL_SHADER_STAGES)
7726 			{
7727 				const std::string& compute_shader_source = empty_string;
7728 				const std::string& fragment_shader_source =
7729 					this->prepare_fragment_shader(input_shader_type, input_source, output_source);
7730 				const std::string& geometry_shader_source =
7731 					this->prepare_geometry_shader(input_shader_type, input_source, output_source);
7732 				const std::string& tess_ctrl_shader_source =
7733 					this->prepare_tess_ctrl_shader_source(input_shader_type, input_source, output_source);
7734 				const std::string& tess_eval_shader_source =
7735 					this->prepare_tess_eval_shader_source(input_shader_type, input_source, output_source);
7736 				const std::string& vertex_shader_source =
7737 					this->prepare_vertex_shader(input_shader_type, input_source, output_source);
7738 
7739 				this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
7740 											geometry_shader_source, fragment_shader_source, compute_shader_source, true,
7741 											false);
7742 			}
7743 			else
7744 			{
7745 				const std::string& fragment_shader_source =
7746 					this->prepare_fragment_shader(input_shader_type, input_source, output_source);
7747 				const std::string& vertex_shader_source =
7748 					this->prepare_vertex_shader(input_shader_type, input_source, output_source);
7749 
7750 				this->execute_positive_test(vertex_shader_source, fragment_shader_source, true, false);
7751 			}
7752 		}
7753 		else
7754 		{
7755 			this->execute_negative_test(input_shader_type, input_source);
7756 			this->execute_negative_test(output_shader_type, output_source);
7757 		}
7758 	}
7759 }
7760 
7761 /** Gets the shader type to test for the outputs
7762  *
7763  * @tparam API              Tested API descriptor
7764  *
7765  * @param input_shader_type The type of input shader that is being tested
7766  **/
7767 template <class API>
get_output_shader_type(const typename TestCaseBase<API>::TestShaderType & input_shader_type)7768 const typename TestCaseBase<API>::TestShaderType InteractionInterfaceArrays2<API>::get_output_shader_type(
7769 	const typename TestCaseBase<API>::TestShaderType& input_shader_type)
7770 {
7771 	switch (input_shader_type)
7772 	{
7773 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7774 		return TestCaseBase<API>::FRAGMENT_SHADER_TYPE;
7775 
7776 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7777 		if (API::USE_ALL_SHADER_STAGES)
7778 		{
7779 			return TestCaseBase<API>::GEOMETRY_SHADER_TYPE;
7780 		}
7781 		else
7782 		{
7783 			return TestCaseBase<API>::VERTEX_SHADER_TYPE;
7784 		}
7785 
7786 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7787 		break;
7788 
7789 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7790 		return TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE;
7791 
7792 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7793 		return TestCaseBase<API>::VERTEX_SHADER_TYPE;
7794 
7795 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7796 		return TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE;
7797 
7798 	default:
7799 		TCU_FAIL("Unrecognized shader type.");
7800 		break;
7801 	}
7802 
7803 	return input_shader_type;
7804 }
7805 
7806 /** Prepare fragment shader
7807  *
7808  * @tparam API              Tested API descriptor
7809  *
7810  * @param input_shader_type The type of input shader that is being tested
7811  * @param input_source      Shader in case we want to test inputs for this shader
7812  * @param output_source     Shader in case we want to test outputs for this shader
7813  **/
7814 template <class API>
prepare_fragment_shader(const typename TestCaseBase<API>::TestShaderType & input_shader_type,const std::string & input_source,const std::string & output_source)7815 const std::string InteractionInterfaceArrays2<API>::prepare_fragment_shader(
7816 	const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7817 	const std::string& output_source)
7818 {
7819 	switch (input_shader_type)
7820 	{
7821 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7822 		return output_source;
7823 
7824 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7825 		return input_source;
7826 
7827 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7828 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7829 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7830 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7831 		break;
7832 
7833 	default:
7834 		TCU_FAIL("Unrecognized shader type.");
7835 		break;
7836 	}
7837 
7838 	return default_fragment_shader_source;
7839 }
7840 
7841 /** Prepare geometry shader
7842  *
7843  * @tparam API              Tested API descriptor
7844  *
7845  * @param input_shader_type The type of input shader that is being tested
7846  * @param input_source      Shader in case we want to test inputs for this shader
7847  * @param output_source     Shader in case we want to test outputs for this shader
7848  **/
7849 template <class API>
prepare_geometry_shader(const typename TestCaseBase<API>::TestShaderType & input_shader_type,const std::string & input_source,const std::string & output_source)7850 const std::string InteractionInterfaceArrays2<API>::prepare_geometry_shader(
7851 	const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7852 	const std::string& output_source)
7853 {
7854 	switch (input_shader_type)
7855 	{
7856 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7857 		if (API::USE_ALL_SHADER_STAGES)
7858 		{
7859 			return output_source;
7860 		}
7861 		break;
7862 
7863 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7864 		return input_source;
7865 
7866 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7867 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7868 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7869 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7870 		break;
7871 
7872 	default:
7873 		TCU_FAIL("Unrecognized shader type.");
7874 		break;
7875 	}
7876 
7877 	return default_geometry_shader_source;
7878 }
7879 
7880 /** Prepare tessellation control shader
7881  *
7882  * @tparam API              Tested API descriptor
7883  *
7884  * @param input_shader_type The type of input shader that is being tested
7885  * @param input_source      Shader in case we want to test inputs for this shader
7886  * @param output_source     Shader in case we want to test outputs for this shader
7887  **/
7888 template <class API>
prepare_tess_ctrl_shader_source(const typename TestCaseBase<API>::TestShaderType & input_shader_type,const std::string & input_source,const std::string & output_source)7889 const std::string InteractionInterfaceArrays2<API>::prepare_tess_ctrl_shader_source(
7890 	const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7891 	const std::string& output_source)
7892 {
7893 	switch (input_shader_type)
7894 	{
7895 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7896 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7897 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7898 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7899 		break;
7900 
7901 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7902 		return input_source;
7903 
7904 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7905 		return output_source;
7906 
7907 	default:
7908 		TCU_FAIL("Unrecognized shader type.");
7909 		break;
7910 	}
7911 
7912 	return default_tc_shader_source;
7913 }
7914 
7915 /** Prepare tessellation evaluation shader
7916  *
7917  * @tparam API              Tested API descriptor
7918  *
7919  * @param input_shader_type The type of input shader that is being tested
7920  * @param input_source      Shader in case we want to test inputs for this shader
7921  * @param output_source     Shader in case we want to test outputs for this shader
7922  **/
7923 template <class API>
prepare_tess_eval_shader_source(const typename TestCaseBase<API>::TestShaderType & input_shader_type,const std::string & input_source,const std::string & output_source)7924 const std::string InteractionInterfaceArrays2<API>::prepare_tess_eval_shader_source(
7925 	const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7926 	const std::string& output_source)
7927 {
7928 	switch (input_shader_type)
7929 	{
7930 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7931 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7932 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7933 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7934 		break;
7935 
7936 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7937 		return output_source;
7938 
7939 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7940 		return input_source;
7941 
7942 	default:
7943 		TCU_FAIL("Unrecognized shader type.");
7944 		break;
7945 	}
7946 
7947 	return default_te_shader_source;
7948 }
7949 
7950 /** Prepare vertex shader
7951  *
7952  * @tparam API              Tested API descriptor
7953  *
7954  * @param input_shader_type The type of input shader that is being tested
7955  * @param input_source      Shader in case we want to test inputs for this shader
7956  * @param output_source     Shader in case we want to test outputs for this shader
7957  **/
7958 template <class API>
prepare_vertex_shader(const typename TestCaseBase<API>::TestShaderType & input_shader_type,const std::string & input_source,const std::string & output_source)7959 const std::string InteractionInterfaceArrays2<API>::prepare_vertex_shader(
7960 	const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source,
7961 	const std::string& output_source)
7962 {
7963 	switch (input_shader_type)
7964 	{
7965 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
7966 		return input_source;
7967 
7968 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
7969 		if (!API::USE_ALL_SHADER_STAGES)
7970 		{
7971 			return output_source;
7972 		}
7973 		break;
7974 
7975 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
7976 		return output_source;
7977 
7978 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
7979 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
7980 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
7981 		break;
7982 
7983 	default:
7984 		TCU_FAIL("Unrecognized shader type.");
7985 		break;
7986 	}
7987 
7988 	return default_vertex_shader_source;
7989 }
7990 
7991 /** Prepare the inputs and outputs shaders
7992  *
7993  * @tparam API                 Tested API descriptor
7994  *
7995  * @param input_shader_type    The type of input shader that is being tested
7996  * @param output_shader_type   The type of output shader that is being tested
7997  * @param input_shader_source  Snippet used to prepare the input shader
7998  * @param output_shader_source Snippet used to prepare the output shader
7999  * @param input_source         Resulting input shader
8000  * @param output_source        Resulting output shader
8001  **/
8002 template <class API>
prepare_sources(const typename TestCaseBase<API>::TestShaderType & input_shader_type,const typename TestCaseBase<API>::TestShaderType & output_shader_type,const std::string * input_shader_source,const std::string * output_shader_source,std::string & input_source,std::string & output_source)8003 void InteractionInterfaceArrays2<API>::prepare_sources(
8004 	const typename TestCaseBase<API>::TestShaderType& input_shader_type,
8005 	const typename TestCaseBase<API>::TestShaderType& output_shader_type, const std::string* input_shader_source,
8006 	const std::string* output_shader_source, std::string& input_source, std::string& output_source)
8007 {
8008 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type)
8009 	{
8010 		input_source += input_shader_source[0];
8011 		output_source += output_shader_source[0];
8012 
8013 		if ((TestCaseBase<API>::GEOMETRY_SHADER_TYPE == input_shader_type) ||
8014 			(TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type) ||
8015 			(TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE == input_shader_type))
8016 		{
8017 			input_source += "[]";
8018 		}
8019 
8020 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8021 		{
8022 			output_source += "[]";
8023 		}
8024 
8025 		input_source += input_shader_source[1];
8026 		output_source += output_shader_source[1];
8027 
8028 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type)
8029 		{
8030 			input_source += "[]";
8031 		}
8032 
8033 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8034 		{
8035 			output_source += "[gl_InvocationID]";
8036 		}
8037 
8038 		input_source += input_shader_source[2];
8039 		output_source += output_shader_source[2];
8040 
8041 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type)
8042 		{
8043 			input_source += "[gl_InvocationID]";
8044 		}
8045 
8046 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8047 		{
8048 			output_source += "[gl_InvocationID]";
8049 		}
8050 
8051 		input_source += input_shader_source[3];
8052 		output_source += output_shader_source[3];
8053 
8054 		if ((TestCaseBase<API>::GEOMETRY_SHADER_TYPE == input_shader_type) ||
8055 			(TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE == input_shader_type))
8056 		{
8057 			input_source += "[0]";
8058 		}
8059 
8060 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type)
8061 		{
8062 			input_source += "[gl_InvocationID]";
8063 		}
8064 
8065 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8066 		{
8067 			output_source += "[gl_InvocationID]";
8068 		}
8069 
8070 		input_source += input_shader_source[4];
8071 		output_source += output_shader_source[4];
8072 
8073 		if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type)
8074 		{
8075 			output_source += "[gl_InvocationID]";
8076 		}
8077 
8078 		output_source += output_shader_source[5];
8079 
8080 		DEFAULT_MAIN_ENDING(input_shader_type, input_source);
8081 		DEFAULT_MAIN_ENDING(output_shader_type, output_source);
8082 	}
8083 }
8084 
8085 /* Generates the shader source code for the InteractionInterfaceArrays3
8086  * array test, and attempts to compile the test shader.
8087  *
8088  * @tparam API               Tested API descriptor
8089  *
8090  * @param tested_shader_type The type of shader that is being tested.
8091  */
8092 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)8093 void InteractionInterfaceArrays3<API>::test_shader_compilation(
8094 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
8095 {
8096 	/* Shader source with invalid uniform block (uniform block cannot be of arrays of arrays type). */
8097 	const std::string invalid_uniform_block_shader_source = "layout(std140) uniform MyUniformBlock\n"
8098 															"{\n"
8099 															"    float f;\n"
8100 															"    int   i;\n"
8101 															"    uint  ui;\n"
8102 															"} myUniformBlocks[2][2];\n\n"
8103 															"void main()\n"
8104 															"{\n";
8105 
8106 	/* Verify that uniform block arrays of arrays type is rejected. */
8107 	{
8108 		std::string source = invalid_uniform_block_shader_source;
8109 
8110 		DEFAULT_MAIN_ENDING(tested_shader_type, source);
8111 
8112 		EXECUTE_SHADER_TEST(API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS, tested_shader_type, source);
8113 	}
8114 }
8115 
8116 /* Generates the shader source code for the InteractionInterfaceArrays4
8117  * array test, and attempts to compile the test shader.
8118  *
8119  * @tparam API              Tested API descriptor
8120  *
8121  * @param input_shader_type The type of shader that is being tested.
8122  */
8123 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType input_shader_type)8124 void InteractionInterfaceArrays4<API>::test_shader_compilation(
8125 	typename TestCaseBase<API>::TestShaderType input_shader_type)
8126 {
8127 	/* Shader source with invalid input (input cannot be of arrays of arrays type). */
8128 	const std::string input_block_shader_source[] = { "in  InOutBlock {\n"
8129 													  "    float inout_variable;\n"
8130 													  "} inout_block",
8131 													  "[2][2];\n"
8132 													  "out float result",
8133 													  ";\n\n"
8134 													  "void main()\n"
8135 													  "{\n"
8136 													  "    result",
8137 													  " = inout_block", "[0][0].inout_variable;\n" };
8138 	/* Shader source with invalid output (output cannot be of arrays of arrays type). */
8139 	const std::string output_block_shader_source[] = { "out InOutBlock {\n"
8140 													   "    float inout_variable;\n"
8141 													   "} inout_block",
8142 													   "[2][2];\n"
8143 													   "\n"
8144 													   "void main()\n"
8145 													   "{\n"
8146 													   "    inout_block",
8147 													   "[0][0].inout_variable = 0.0;\n"
8148 													   "    inout_block",
8149 													   "[0][1].inout_variable = 1.0;\n"
8150 													   "    inout_block",
8151 													   "[1][0].inout_variable = 2.0;\n"
8152 													   "    inout_block",
8153 													   "[1][1].inout_variable = 3.0;\n" };
8154 
8155 	const typename TestCaseBase<API>::TestShaderType& output_shader_type =
8156 		this->get_output_shader_type(input_shader_type);
8157 	std::string input_source;
8158 	std::string output_source;
8159 
8160 	this->prepare_sources(input_shader_type, output_shader_type, input_block_shader_source, output_block_shader_source,
8161 						  input_source, output_source);
8162 
8163 	/* Verify that INPUTs and OUTPUTs arrays of arrays type is rejected. */
8164 	if ((TestCaseBase<API>::VERTEX_SHADER_TYPE != input_shader_type) &&
8165 		(TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type))
8166 	{
8167 		if (API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS && API::ALLOW_IN_OUT_INTERFACE_BLOCKS)
8168 		{
8169 
8170 			if (API::USE_ALL_SHADER_STAGES)
8171 			{
8172 				const std::string& compute_shader_source = empty_string;
8173 				const std::string& fragment_shader_source =
8174 					this->prepare_fragment_shader(input_shader_type, input_source, output_source);
8175 				const std::string& geometry_shader_source =
8176 					this->prepare_geometry_shader(input_shader_type, input_source, output_source);
8177 				const std::string& tess_ctrl_shader_source =
8178 					this->prepare_tess_ctrl_shader_source(input_shader_type, input_source, output_source);
8179 				const std::string& tess_eval_shader_source =
8180 					this->prepare_tess_eval_shader_source(input_shader_type, input_source, output_source);
8181 				const std::string& vertex_shader_source =
8182 					this->prepare_vertex_shader(input_shader_type, input_source, output_source);
8183 
8184 				this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
8185 											geometry_shader_source, fragment_shader_source, compute_shader_source, true,
8186 											false);
8187 			}
8188 			else
8189 			{
8190 				const std::string& fragment_shader_source =
8191 					this->prepare_fragment_shader(input_shader_type, input_source, output_source);
8192 				const std::string& vertex_shader_source =
8193 					this->prepare_vertex_shader(input_shader_type, input_source, output_source);
8194 
8195 				this->execute_positive_test(vertex_shader_source, fragment_shader_source, true, false);
8196 			}
8197 		}
8198 		else
8199 		{
8200 			this->execute_negative_test(input_shader_type, input_source);
8201 			this->execute_negative_test(output_shader_type, output_source);
8202 		}
8203 	}
8204 }
8205 
8206 /** Calulate smallest denominator for values over 1
8207  *
8208  * @param value Value in question
8209  *
8210  * @return Smallest denominator
8211  **/
findSmallestDenominator(const size_t value)8212 size_t findSmallestDenominator(const size_t value)
8213 {
8214 	/* Skip 0 and 1 */
8215 	for (size_t i = 2; i < value; ++i)
8216 	{
8217 		if (0 == value % i)
8218 		{
8219 			return i;
8220 		}
8221 	}
8222 
8223 	return value;
8224 }
8225 
8226 /** Check if left is bigger than right
8227  *
8228  * @tparam T Type of values
8229 
8230  * @param l  Left value
8231  * @param r  Right value
8232  *
8233  * @return true if l > r, false otherwise
8234  **/
8235 template <class T>
more(const T & l,const T & r)8236 bool more(const T& l, const T& r)
8237 {
8238 	return l > r;
8239 }
8240 
8241 /** Prepare dimensions of array with given number of entries
8242  *
8243  * @tparam API       Tested API descriptor
8244  *
8245  * @param n_entries  Number of entries
8246  * @param dimensions Storage for dimesnions
8247  **/
8248 template <class API>
prepareDimensions(size_t n_entries,std::vector<size_t> & dimensions)8249 void prepareDimensions(size_t n_entries, std::vector<size_t>& dimensions)
8250 {
8251 	if (dimensions.empty())
8252 		return;
8253 
8254 	const size_t last = dimensions.size() - 1;
8255 
8256 	/* Calculate */
8257 	for (size_t i = 0; i < last; ++i)
8258 	{
8259 		const size_t denom = findSmallestDenominator(n_entries);
8260 
8261 		n_entries /= denom;
8262 
8263 		dimensions[i] = denom;
8264 	}
8265 
8266 	dimensions[last] = n_entries;
8267 
8268 	/* Sort */
8269 	std::sort(dimensions.begin(), dimensions.end(), more<size_t>);
8270 }
8271 
8272 /* Generates the shader source code for the AtomicDeclarationTest
8273  * and attempts to compile each shader
8274  *
8275  * @tparam API               Tested API descriptor
8276  *
8277  * @param tested_shader_type The type of shader that is being tested
8278  */
8279 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)8280 void AtomicDeclarationTest<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
8281 {
8282 	static const char* indent_step		   = "    ";
8283 	static const char* uniform_atomic_uint = "layout(binding = 0) uniform atomic_uint";
8284 
8285 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
8286 
8287 	std::string			comment;
8288 	std::vector<size_t> dimensions;
8289 	std::string			indent;
8290 	std::string			indexing;
8291 	std::string			invalid_definition = uniform_atomic_uint;
8292 	std::string			invalid_iteration;
8293 	std::string			invalid_shader_source;
8294 	std::string			loop_end;
8295 	glw::GLint			max_atomics = 0;
8296 	glw::GLenum			pname		= 0;
8297 	std::string			valid_shader_source;
8298 	std::string			valid_definition = uniform_atomic_uint;
8299 	std::string			valid_iteration;
8300 
8301 	/* Select pname of max for stage */
8302 	switch (tested_shader_type)
8303 	{
8304 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8305 		pname = GL_MAX_COMPUTE_ATOMIC_COUNTERS;
8306 		break;
8307 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8308 		pname = GL_MAX_FRAGMENT_ATOMIC_COUNTERS;
8309 		break;
8310 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8311 		pname = GL_MAX_GEOMETRY_ATOMIC_COUNTERS;
8312 		break;
8313 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8314 		pname = GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS;
8315 		break;
8316 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8317 		pname = GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS;
8318 		break;
8319 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8320 		pname = GL_MAX_VERTEX_ATOMIC_COUNTERS;
8321 		break;
8322 	default:
8323 		TCU_FAIL("Invalid enum");
8324 		break;
8325 	}
8326 
8327 	/* Get maximum */
8328 	gl.getIntegerv(pname, &max_atomics);
8329 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8330 
8331 	if (0 == max_atomics)
8332 	{
8333 		/* Not supported - skip */
8334 		return;
8335 	}
8336 	else
8337 	{
8338 		dimensions.resize(API::MAX_ARRAY_DIMENSIONS);
8339 		prepareDimensions<API>(max_atomics, dimensions);
8340 	}
8341 
8342 	/* Prepare parts of shader */
8343 	for (size_t i = API::MAX_ARRAY_DIMENSIONS; i != 0; --i)
8344 	{
8345 		char it[16];
8346 		char max[16];
8347 
8348 		indent += indent_step;
8349 
8350 		loop_end.insert(0, "}\n");
8351 		loop_end.insert(0, indent);
8352 
8353 		sprintf(it, "i%u", (unsigned int)(API::MAX_ARRAY_DIMENSIONS - i));
8354 
8355 		indexing += "[";
8356 		indexing += it;
8357 		indexing += "]";
8358 
8359 		sprintf(max, "%u", (unsigned int)(dimensions[i - 1]));
8360 
8361 		valid_definition += "[";
8362 		valid_definition += max;
8363 		valid_definition += "]";
8364 
8365 		valid_iteration += indent;
8366 		valid_iteration += "for (uint ";
8367 		valid_iteration += it;
8368 		valid_iteration += " = 0; ";
8369 		valid_iteration += it;
8370 		valid_iteration += " < ";
8371 		valid_iteration += max;
8372 		valid_iteration += "; ++";
8373 		valid_iteration += it;
8374 		valid_iteration += ")\n";
8375 		valid_iteration += indent;
8376 		valid_iteration += "{\n";
8377 
8378 		if (1 == i)
8379 		{
8380 			sprintf(max, "%u", (unsigned int)(dimensions[i - 1] + 1));
8381 		}
8382 		invalid_definition += "[";
8383 		invalid_definition += max;
8384 		invalid_definition += "]";
8385 
8386 		invalid_iteration += indent;
8387 		invalid_iteration += "for (uint ";
8388 		invalid_iteration += it;
8389 		invalid_iteration += " = 0; ";
8390 		invalid_iteration += it;
8391 		invalid_iteration += " < ";
8392 		invalid_iteration += max;
8393 		invalid_iteration += "; ++";
8394 		invalid_iteration += it;
8395 		invalid_iteration += ")\n";
8396 		invalid_iteration += indent;
8397 		invalid_iteration += "{\n";
8398 	}
8399 
8400 	{
8401 		char max[16];
8402 
8403 		sprintf(max, "%u", (unsigned int)(max_atomics));
8404 		comment += "/* MAX_*_ATOMIC_COUNTERS = ";
8405 		comment += max;
8406 		comment += " */\n";
8407 	}
8408 
8409 	/* Prepare invalid source */
8410 	invalid_shader_source += comment;
8411 	invalid_shader_source += invalid_definition;
8412 	invalid_shader_source += " a;\n\nvoid main()\n{\n";
8413 	invalid_shader_source += invalid_iteration;
8414 	invalid_shader_source += indent;
8415 	invalid_shader_source += indent_step;
8416 	invalid_shader_source += "atomicCounterIncrement( a";
8417 	invalid_shader_source += indexing;
8418 	invalid_shader_source += " );\n";
8419 	invalid_shader_source += loop_end;
8420 
8421 	/* Prepare valid source */
8422 	valid_shader_source += comment;
8423 	valid_shader_source += valid_definition;
8424 	valid_shader_source += " a;\n\nvoid main()\n{\n";
8425 	valid_shader_source += valid_iteration;
8426 	valid_shader_source += indent;
8427 	valid_shader_source += indent_step;
8428 	valid_shader_source += "atomicCounterIncrement( a";
8429 	valid_shader_source += indexing;
8430 	valid_shader_source += " );\n";
8431 	valid_shader_source += loop_end;
8432 
8433 	/* End main */
8434 	DEFAULT_MAIN_ENDING(tested_shader_type, invalid_shader_source);
8435 	DEFAULT_MAIN_ENDING(tested_shader_type, valid_shader_source);
8436 
8437 	/* Execute test */
8438 	EXECUTE_POSITIVE_TEST(tested_shader_type, valid_shader_source, true, false);
8439 
8440 	/* Expect build failure for invalid shader source */
8441 	{
8442 		bool negative_build_test_result = false;
8443 
8444 		try
8445 		{
8446 			EXECUTE_POSITIVE_TEST(tested_shader_type, invalid_shader_source, true, false);
8447 		}
8448 		catch (...)
8449 		{
8450 			negative_build_test_result = true;
8451 		}
8452 
8453 		if (false == negative_build_test_result)
8454 		{
8455 			TCU_FAIL("It was expected that build process will fail");
8456 		}
8457 	}
8458 }
8459 
8460 /* Generates the shader source code for the AtomicUsageTest
8461  * and attempts to compile each shader
8462  *
8463  * @tparam API               Tested API descriptor
8464  *
8465  * @param tested_shader_type The type of shader that is being tested
8466  */
8467 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)8468 void AtomicUsageTest<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)
8469 {
8470 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
8471 
8472 	glw::GLint  max_atomics  = 0;
8473 	glw::GLint  max_bindings = 0;
8474 	glw::GLint  max_size	 = 0;
8475 	glw::GLenum pname		 = 0;
8476 
8477 	/* Select pname of max for stage */
8478 	switch (tested_shader_type)
8479 	{
8480 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8481 		pname = GL_MAX_COMPUTE_ATOMIC_COUNTERS;
8482 		break;
8483 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8484 		pname = GL_MAX_FRAGMENT_ATOMIC_COUNTERS;
8485 		break;
8486 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8487 		pname = GL_MAX_GEOMETRY_ATOMIC_COUNTERS;
8488 		break;
8489 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8490 		pname = GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS;
8491 		break;
8492 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8493 		pname = GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS;
8494 		break;
8495 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8496 		pname = GL_MAX_VERTEX_ATOMIC_COUNTERS;
8497 		break;
8498 	default:
8499 		TCU_FAIL("Invalid enum");
8500 		break;
8501 	}
8502 
8503 	/* Get limits */
8504 	gl.getIntegerv(pname, &max_atomics);
8505 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8506 
8507 	gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings);
8508 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8509 
8510 	gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, &max_size);
8511 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8512 
8513 	if (0 == max_atomics)
8514 	{
8515 		/* Not supported - skip */
8516 		return;
8517 	}
8518 
8519 	const glw::GLuint last_binding = (glw::GLuint)max_bindings - 1;
8520 	const glw::GLuint offset	   = (glw::GLuint)max_size / 2;
8521 	glw::GLuint		  n_entries =
8522 		std::min((glw::GLuint)(max_size - offset) / (glw::GLuint)sizeof(glw::GLuint), (glw::GLuint)max_atomics);
8523 
8524 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
8525 	{
8526 		glw::GLint max_uniform_locations = 0;
8527 
8528 		gl.getIntegerv(GL_MAX_UNIFORM_LOCATIONS, &max_uniform_locations);
8529 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8530 
8531 		max_atomics = std::min(max_atomics, (max_uniform_locations - 1));
8532 		n_entries   = (glw::GLuint)std::min((glw::GLint)n_entries, (max_uniform_locations - 1));
8533 	}
8534 
8535 	execute(tested_shader_type, last_binding, 0 /* offset */, max_atomics);
8536 	execute(tested_shader_type, last_binding, offset, n_entries);
8537 }
8538 
8539 /* Generates the shader source code for the AtomicUsageTest
8540  * and attempts to compile each shader
8541  *
8542  * @tparam API               Tested API descriptor
8543  *
8544  * @param tested_shader_type The type of shader that is being tested
8545  * @param binding            Binding index
8546  * @param offset             Offset of data
8547  * @param n_entries          Number of entries in array
8548  */
8549 template <class API>
execute(typename TestCaseBase<API>::TestShaderType tested_shader_type,glw::GLuint binding,glw::GLuint offset,glw::GLuint n_entries)8550 void AtomicUsageTest<API>::execute(typename TestCaseBase<API>::TestShaderType tested_shader_type, glw::GLuint binding,
8551 								   glw::GLuint offset, glw::GLuint n_entries)
8552 {
8553 	static const char* indent_step		   = "    ";
8554 	static const char* layout_binding	  = "layout(binding = ";
8555 	static const char* layout_offset	   = ", offset = ";
8556 	static const char* uniform_atomic_uint = ") uniform atomic_uint";
8557 
8558 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
8559 
8560 	std::string			comment;
8561 	std::vector<size_t> dimensions;
8562 	std::string			indent;
8563 	std::string			indexing;
8564 	std::string			loop_end;
8565 	std::string			result;
8566 	std::string			valid_shader_source;
8567 	std::string			valid_definition = layout_binding;
8568 	std::string			valid_iteration;
8569 	std::string			varying_definition;
8570 
8571 	dimensions.resize(API::MAX_ARRAY_DIMENSIONS);
8572 	prepareDimensions<API>(n_entries, dimensions);
8573 
8574 	/* Prepare parts of shader */
8575 
8576 	/* Append binding */
8577 	{
8578 		char buffer[16];
8579 		sprintf(buffer, "%u", static_cast<unsigned int>(binding));
8580 		valid_definition += buffer;
8581 		valid_definition += layout_offset;
8582 		sprintf(buffer, "%u", static_cast<unsigned int>(offset));
8583 		valid_definition += buffer;
8584 		valid_definition += uniform_atomic_uint;
8585 	}
8586 
8587 	for (size_t i = API::MAX_ARRAY_DIMENSIONS; i != 0; --i)
8588 	{
8589 		char it[16];
8590 		char max[16];
8591 
8592 		indent += indent_step;
8593 
8594 		loop_end.insert(0, "}\n");
8595 		loop_end.insert(0, indent);
8596 
8597 		sprintf(it, "i%u", (unsigned int)(API::MAX_ARRAY_DIMENSIONS - i));
8598 
8599 		indexing += "[";
8600 		indexing += it;
8601 		indexing += "]";
8602 
8603 		sprintf(max, "%u", (unsigned int)(dimensions[i - 1]));
8604 		valid_definition += "[";
8605 		valid_definition += max;
8606 		valid_definition += "]";
8607 
8608 		valid_iteration += indent;
8609 		valid_iteration += "for (uint ";
8610 		valid_iteration += it;
8611 		valid_iteration += " = 0; ";
8612 		valid_iteration += it;
8613 		valid_iteration += " < ";
8614 		valid_iteration += max;
8615 		valid_iteration += "; ++";
8616 		valid_iteration += it;
8617 		valid_iteration += ")\n";
8618 		valid_iteration += indent;
8619 		valid_iteration += "{\n";
8620 	}
8621 
8622 	{
8623 		char max[16];
8624 
8625 		sprintf(max, "%u", (unsigned int)(n_entries));
8626 		comment += "/* Number of atomic counters = ";
8627 		comment += max;
8628 		comment += " */\n";
8629 	}
8630 
8631 	/* Select varyings and result */
8632 	switch (tested_shader_type)
8633 	{
8634 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8635 		result			   = "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n";
8636 		varying_definition = "writeonly uniform image2D uni_image;\n"
8637 							 "\n";
8638 		break;
8639 
8640 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8641 		result			   = "    color = vec4(result);\n";
8642 		varying_definition = "out vec4 color;\n"
8643 							 "\n";
8644 		break;
8645 
8646 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8647 		result = "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8648 				 "    fs_result = result;\n"
8649 				 "    EmitVertex();\n"
8650 				 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8651 				 "    fs_result = result;\n"
8652 				 "    EmitVertex();\n"
8653 				 "    gl_Position  = vec4(1, -1, 0, 1);\n"
8654 				 "    fs_result = result;\n"
8655 				 "    EmitVertex();\n"
8656 				 "    gl_Position  = vec4(1, 1, 0, 1);\n"
8657 				 "    fs_result = result;\n"
8658 				 "    EmitVertex();\n";
8659 		varying_definition = "out float fs_result;\n"
8660 							 "\n";
8661 		break;
8662 
8663 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8664 		result = "    tcs_result[gl_InvocationID] = result;\n"
8665 				 "\n"
8666 				 "    gl_TessLevelOuter[0] = 1.0;\n"
8667 				 "    gl_TessLevelOuter[1] = 1.0;\n"
8668 				 "    gl_TessLevelOuter[2] = 1.0;\n"
8669 				 "    gl_TessLevelOuter[3] = 1.0;\n"
8670 				 "    gl_TessLevelInner[0] = 1.0;\n"
8671 				 "    gl_TessLevelInner[1] = 1.0;\n";
8672 		varying_definition = "out float tcs_result[];\n"
8673 							 "\n";
8674 		break;
8675 
8676 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8677 		result			   = "    fs_result = result;\n";
8678 		varying_definition = "out float fs_result;\n"
8679 							 "\n";
8680 		break;
8681 
8682 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8683 		result			   = "    fs_result = result;\n";
8684 		varying_definition = "out float fs_result;\n"
8685 							 "\n";
8686 		break;
8687 
8688 	default:
8689 		TCU_FAIL("Invalid enum");
8690 		break;
8691 	};
8692 
8693 	/* Prepare valid source */
8694 	valid_shader_source += varying_definition;
8695 	valid_shader_source += comment;
8696 	valid_shader_source += valid_definition;
8697 	valid_shader_source += " a;\n\nvoid main()\n{\n    uint sum = 0u;\n";
8698 	valid_shader_source += valid_iteration;
8699 	valid_shader_source += indent;
8700 	valid_shader_source += indent_step;
8701 	valid_shader_source += "sum += atomicCounterIncrement( a";
8702 	valid_shader_source += indexing;
8703 	valid_shader_source += " );\n";
8704 	valid_shader_source += loop_end;
8705 	valid_shader_source += "\n"
8706 						   "    float result = 0.0;\n"
8707 						   "\n"
8708 						   "    if (16u < sum)\n"
8709 						   "    {\n"
8710 						   "         result = 1.0;\n"
8711 						   "    }\n";
8712 	valid_shader_source += result;
8713 	valid_shader_source += shader_end;
8714 
8715 	/* Build program */
8716 	{
8717 		const std::string* cs  = &empty_string;
8718 		const std::string* vs  = &default_vertex_shader_source;
8719 		const std::string* tcs = &empty_string;
8720 		const std::string* tes = &empty_string;
8721 		const std::string* gs  = &empty_string;
8722 		const std::string* fs  = &pass_fragment_shader_source;
8723 
8724 		switch (tested_shader_type)
8725 		{
8726 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
8727 			cs = &valid_shader_source;
8728 			vs = &empty_string;
8729 			fs = &empty_string;
8730 			break;
8731 
8732 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8733 			fs = &valid_shader_source;
8734 			break;
8735 
8736 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8737 			gs = &valid_shader_source;
8738 			break;
8739 
8740 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
8741 			tcs = &valid_shader_source;
8742 			tes = &pass_te_shader_source;
8743 			break;
8744 
8745 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8746 			tcs = &default_tc_shader_source;
8747 			tes = &valid_shader_source;
8748 			break;
8749 
8750 		case TestCaseBase<API>::VERTEX_SHADER_TYPE:
8751 			vs = &valid_shader_source;
8752 			break;
8753 
8754 		default:
8755 			TCU_FAIL("Invalid enum");
8756 			break;
8757 		};
8758 
8759 		if (API::USE_ALL_SHADER_STAGES)
8760 		{
8761 			this->execute_positive_test(*vs, *tcs, *tes, *gs, *fs, *cs, false, false);
8762 		}
8763 		else
8764 		{
8765 			this->execute_positive_test(*vs, *fs, false, false);
8766 		}
8767 	}
8768 
8769 	gl.useProgram(this->program_object_id);
8770 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
8771 
8772 	/* Prepare buffer */
8773 	glw::GLuint				 buffer_object_id = 0;
8774 	std::vector<glw::GLuint> buffer_data;
8775 	const size_t			 start_pos		  = offset / 4;
8776 	const size_t			 last_pos		  = start_pos + n_entries;
8777 	const size_t			 buffer_data_size = last_pos * sizeof(glw::GLuint);
8778 
8779 	gl.genBuffers(1, &buffer_object_id);
8780 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed.");
8781 
8782 	gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer_object_id);
8783 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed.");
8784 
8785 	buffer_data.resize(start_pos + n_entries);
8786 	for (size_t i = 0; i < n_entries; ++i)
8787 	{
8788 		buffer_data[start_pos + i] = (glw::GLuint)i;
8789 	}
8790 
8791 	gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, buffer_data_size, &buffer_data[0], GL_STATIC_DRAW);
8792 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed.");
8793 
8794 	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, binding, buffer_object_id);
8795 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed.");
8796 
8797 	/* Run program */
8798 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type)
8799 	{
8800 		glw::GLuint framebuffer_object_id = 0;
8801 		glw::GLuint texture_object_id	 = 0;
8802 		glw::GLuint vao_id				  = 0;
8803 
8804 		gl.genTextures(1, &texture_object_id);
8805 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
8806 
8807 		gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
8808 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
8809 
8810 		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
8811 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
8812 
8813 		gl.genFramebuffers(1, &framebuffer_object_id);
8814 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
8815 
8816 		gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
8817 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
8818 
8819 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
8820 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
8821 
8822 		gl.viewport(0, 0, 1, 1);
8823 		GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
8824 
8825 		gl.genVertexArrays(1, &vao_id);
8826 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
8827 
8828 		gl.bindVertexArray(vao_id);
8829 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
8830 
8831 		switch (tested_shader_type)
8832 		{
8833 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
8834 		case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
8835 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
8836 			gl.drawArrays(GL_POINTS, 0, 1);
8837 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
8838 			break;
8839 
8840 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
8841 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
8842 			/* Tesselation patch set up */
8843 			gl.patchParameteri(GL_PATCH_VERTICES, 1);
8844 			GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
8845 
8846 			gl.drawArrays(GL_PATCHES, 0, 1);
8847 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
8848 			break;
8849 
8850 		default:
8851 			TCU_FAIL("Invalid enum");
8852 			break;
8853 		}
8854 
8855 		gl.memoryBarrier(GL_ALL_BARRIER_BITS);
8856 		GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier.");
8857 
8858 		gl.bindTexture(GL_TEXTURE_2D, 0);
8859 		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
8860 		gl.bindVertexArray(0);
8861 		gl.deleteTextures(1, &texture_object_id);
8862 		gl.deleteFramebuffers(1, &framebuffer_object_id);
8863 		gl.deleteVertexArrays(1, &vao_id);
8864 		GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
8865 	}
8866 	else
8867 	{
8868 		gl.dispatchCompute(1, 1, 1);
8869 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
8870 
8871 		gl.memoryBarrier(GL_ALL_BARRIER_BITS);
8872 		GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier.");
8873 	}
8874 
8875 	/* Verify results */
8876 	bool test_result = true;
8877 
8878 	const glw::GLuint* results =
8879 		(glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /* offset */, buffer_data_size, GL_MAP_READ_BIT);
8880 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBufferRange");
8881 
8882 	/* Anything before start position should be 0 */
8883 	for (size_t i = 0; i < start_pos; ++i)
8884 	{
8885 		if (0 != results[i])
8886 		{
8887 			test_result = false;
8888 			break;
8889 		}
8890 	}
8891 
8892 	/* Anything from start_pos should be incremented by 1 */
8893 	int diff = 0;
8894 	for (size_t i = 0; i < n_entries; ++i)
8895 	{
8896 		/* Tesselation evaluation can be called several times
8897 		 In here, check the increment is consistent over all results.
8898 		 */
8899 		if (tested_shader_type == TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE)
8900 		{
8901 			if (i == 0)
8902 			{
8903 				diff = static_cast<int>(results[i + start_pos]) - static_cast<int>(i);
8904 				if (diff <= 0)
8905 				{
8906 					test_result = false;
8907 					break;
8908 				}
8909 			}
8910 			else if ((static_cast<int>(results[i + start_pos]) - static_cast<int>(i)) != diff)
8911 			{
8912 				test_result = false;
8913 				break;
8914 			}
8915 		}
8916 		else
8917 		{
8918 			if (i + 1 != results[i + start_pos])
8919 			{
8920 				test_result = false;
8921 				break;
8922 			}
8923 		}
8924 	}
8925 
8926 	gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
8927 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
8928 
8929 	/* Deallocate any resources used. */
8930 	gl.deleteBuffers(1, &buffer_object_id);
8931 	this->delete_objects();
8932 
8933 	if (false == test_result)
8934 	{
8935 		TCU_FAIL("Invalid results.");
8936 	}
8937 }
8938 
8939 /* Generates the shader source code for the SubroutineFunctionCalls1
8940  * array tests, attempts to build and execute test program
8941  *
8942  * @tparam API               Tested API descriptor
8943  *
8944  * @param tested_shader_type The type of shader that is being tested
8945  */
8946 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)8947 void SubroutineFunctionCalls1<API>::test_shader_compilation(
8948 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
8949 {
8950 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
8951 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
8952 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
8953 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
8954 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
8955 
8956 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
8957 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
8958 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
8959 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
8960 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
8961 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
8962 
8963 	const std::string iteration_loop_end = "                }\n"
8964 										   "            }\n"
8965 										   "        }\n"
8966 										   "    }\n";
8967 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
8968 											 "    {\n"
8969 											 "        for (uint b = 0u; b < 2u; b++)\n"
8970 											 "        {\n"
8971 											 "            for (uint c = 0u; c < 2u; c++)\n"
8972 											 "            {\n"
8973 											 "                for (uint d = 0u; d < 2u; d++)\n"
8974 											 "                {\n";
8975 	const glcts::test_var_type* var_types_set = var_types_set_es;
8976 	size_t						num_var_types = num_var_types_es;
8977 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
8978 
8979 	if (API::USE_DOUBLE)
8980 	{
8981 		var_types_set = var_types_set_gl;
8982 		num_var_types = num_var_types_gl;
8983 	}
8984 
8985 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
8986 	{
8987 		_supported_variable_types_map_const_iterator var_iterator =
8988 			supported_variable_types_map.find(var_types_set[var_type_index]);
8989 
8990 		if (var_iterator != supported_variable_types_map.end())
8991 		{
8992 			std::string iterator_declaration = "    " + var_iterator->second.iterator_type +
8993 											   " iterator = " + var_iterator->second.iterator_initialization + ";\n";
8994 
8995 			std::string function_definition;
8996 			std::string function_use;
8997 			std::string verification;
8998 
8999 			function_definition += "// Subroutine types\n"
9000 								   "subroutine void out_routine_type(out ";
9001 			function_definition += var_iterator->second.type;
9002 			function_definition += " output_array[2][2][2][2]);\n\n"
9003 								   "// Subroutine definitions\n"
9004 								   "subroutine(out_routine_type) void original_routine(out ";
9005 			function_definition += var_iterator->second.type;
9006 			function_definition += " output_array[2][2][2][2]) {\n";
9007 			function_definition += iterator_declaration;
9008 			function_definition += iteration_loop_start;
9009 			function_definition += "                                   output_array[a][b][c][d] = " +
9010 								   var_iterator->second.variable_type_initializer1 + ";\n";
9011 			function_definition +=
9012 				"                                   iterator += " + var_iterator->second.iterator_type + "(1);\n";
9013 			function_definition += iteration_loop_end;
9014 			function_definition += "}\n\n";
9015 			function_definition += "subroutine(out_routine_type) void new_routine(out ";
9016 			function_definition += var_iterator->second.type;
9017 			function_definition += " output_array[2][2][2][2]) {\n";
9018 			function_definition += iterator_declaration;
9019 			function_definition += iteration_loop_start;
9020 			function_definition += "                                   output_array[a][b][c][d] = " +
9021 								   var_iterator->second.variable_type_initializer1 + ";\n";
9022 			function_definition +=
9023 				"                                   iterator -= " + var_iterator->second.iterator_type + "(1);\n";
9024 			function_definition += iteration_loop_end;
9025 			function_definition += "}\n\n"
9026 								   "// Subroutine uniform\n"
9027 								   "subroutine uniform out_routine_type routine;\n";
9028 
9029 			function_use = "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
9030 			function_use += "    routine(my_array);";
9031 
9032 			verification = iterator_declaration;
9033 			verification += "    float result = 1.0;\n";
9034 			verification += iteration_loop_start;
9035 			verification += "                                   if (my_array[a][b][c][d] " +
9036 							var_iterator->second.specific_element +
9037 							" != iterator)\n"
9038 							"                                   {\n"
9039 							"                                       result = 0.0;\n"
9040 							"                                   }\n"
9041 							"                                   iterator += " +
9042 							var_iterator->second.iterator_type + "(1);\n";
9043 			verification += iteration_loop_end;
9044 
9045 			if (false == test_compute)
9046 			{
9047 				execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, true);
9048 				execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, false);
9049 			}
9050 			else
9051 			{
9052 				execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, true);
9053 				execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, false);
9054 			}
9055 
9056 			/* Deallocate any resources used. */
9057 			this->delete_objects();
9058 		} /* if var_type iterator found */
9059 		else
9060 		{
9061 			TCU_FAIL("Type not found.");
9062 		}
9063 	} /* for (int var_type_index = 0; ...) */
9064 }
9065 
9066 /** Executes test for compute program
9067  *
9068  * @tparam API                  Tested API descriptor
9069  *
9070  * @param tested_shader_type    The type of shader that is being tested
9071  * @param function_definition   Definition used to prepare shader
9072  * @param function_use          Use of definition
9073  * @param verification          Result verification
9074  * @param use_original          Selects if "original_routine" - true or "new_routine" is choosen
9075  * @param expect_invalid_result Does test expects invalid results
9076  **/
9077 template <class API>
execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification,bool use_original,bool expect_invalid_result)9078 void SubroutineFunctionCalls1<API>::execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
9079 														  const std::string& function_definition,
9080 														  const std::string& function_use,
9081 														  const std::string& verification, bool use_original,
9082 														  bool expect_invalid_result)
9083 {
9084 	const std::string& compute_shader_source =
9085 		prepare_compute_shader(tested_shader_type, function_definition, function_use, verification);
9086 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
9087 
9088 	this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string,
9089 								compute_shader_source, false, false);
9090 
9091 	/* We are now ready to verify whether the returned size is correct. */
9092 	unsigned char	  buffer[4]			 = { 0 };
9093 	glw::GLuint		   framebuffer_object_id = 0;
9094 	glw::GLint		   location				 = -1;
9095 	glw::GLuint		   routine_index		 = -1;
9096 	glw::GLuint		   routine_location		 = -1;
9097 	const glw::GLchar* routine_name			 = "original_routine";
9098 	const glw::GLenum  shader_type			 = GL_COMPUTE_SHADER;
9099 	glw::GLuint		   texture_object_id	 = 0;
9100 
9101 	if (false == use_original)
9102 	{
9103 		routine_name = "new_routine";
9104 	}
9105 
9106 	gl.useProgram(this->program_object_id);
9107 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
9108 
9109 	/* Select subroutine */
9110 	routine_index = gl.getSubroutineIndex(this->program_object_id, shader_type, routine_name);
9111 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() failed.");
9112 
9113 	routine_location = gl.getSubroutineUniformLocation(this->program_object_id, shader_type, "routine");
9114 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() failed.");
9115 
9116 	if (0 != routine_location)
9117 	{
9118 		TCU_FAIL("Subroutine location is invalid");
9119 	}
9120 
9121 	gl.uniformSubroutinesuiv(shader_type, 1, &routine_index);
9122 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() failed.");
9123 
9124 	/* Prepare texture */
9125 	gl.genTextures(1, &texture_object_id);
9126 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
9127 
9128 	gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
9129 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
9130 
9131 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
9132 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
9133 
9134 	gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
9135 						GL_WRITE_ONLY, GL_RGBA8);
9136 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed.");
9137 
9138 	location = gl.getUniformLocation(this->program_object_id, "uni_image");
9139 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed.");
9140 
9141 	if (-1 == location)
9142 	{
9143 		TCU_FAIL("Uniform is inactive");
9144 	}
9145 
9146 	gl.uniform1i(location, 0 /* image unit */);
9147 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed.");
9148 
9149 	/* Execute */
9150 	gl.dispatchCompute(1, 1, 1);
9151 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9152 
9153 	/* Verify */
9154 	gl.genFramebuffers(1, &framebuffer_object_id);
9155 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
9156 
9157 	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
9158 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
9159 
9160 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
9161 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
9162 
9163 	gl.viewport(0, 0, 1, 1);
9164 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
9165 
9166 	gl.readBuffer(GL_COLOR_ATTACHMENT0);
9167 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
9168 
9169 	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
9170 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
9171 
9172 	if ((buffer[0] != 255) != expect_invalid_result)
9173 	{
9174 		TCU_FAIL("Invalid result was returned.");
9175 	}
9176 
9177 	/* Delete generated objects. */
9178 	gl.useProgram(0);
9179 	gl.bindTexture(GL_TEXTURE_2D, 0);
9180 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
9181 
9182 	gl.deleteProgram(this->program_object_id);
9183 	this->program_object_id = 0;
9184 
9185 	gl.deleteTextures(1, &texture_object_id);
9186 	gl.deleteFramebuffers(1, &framebuffer_object_id);
9187 	GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
9188 }
9189 
9190 /** Executes test for draw program
9191  *
9192  * @tparam API                  Tested API descriptor
9193  *
9194  * @param tested_shader_type    The type of shader that is being tested
9195  * @param function_definition   Definition used to prepare shader
9196  * @param function_use          Use of definition
9197  * @param verification          Result verification
9198  * @param use_original          Selects if "original_routine" - true or "new_routine" is choosen
9199  * @param expect_invalid_result Does test expects invalid results
9200  **/
9201 template <class API>
execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification,bool use_original,bool expect_invalid_result)9202 void SubroutineFunctionCalls1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type,
9203 													  const std::string&						 function_definition,
9204 													  const std::string& function_use, const std::string& verification,
9205 													  bool use_original, bool expect_invalid_result)
9206 {
9207 	const glw::Functions& gl = this->context_id.getRenderContext().getFunctions();
9208 
9209 	if (API::USE_ALL_SHADER_STAGES)
9210 	{
9211 		const std::string& compute_shader_source = empty_string;
9212 		const std::string& fragment_shader_source =
9213 			this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
9214 		const std::string& geometry_shader_source =
9215 			this->prepare_geometry_shader(tested_shader_type, function_definition, function_use, verification);
9216 		const std::string& tess_ctrl_shader_source =
9217 			this->prepare_tess_ctrl_shader(tested_shader_type, function_definition, function_use, verification);
9218 		const std::string& tess_eval_shader_source =
9219 			this->prepare_tess_eval_shader(tested_shader_type, function_definition, function_use, verification);
9220 		const std::string& vertex_shader_source =
9221 			this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
9222 
9223 		switch (tested_shader_type)
9224 		{
9225 		case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */
9226 		case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9227 			this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
9228 			break;
9229 
9230 		case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9231 		case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9232 		case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
9233 		case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9234 			this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source,
9235 										geometry_shader_source, fragment_shader_source, compute_shader_source, false,
9236 										false);
9237 			break;
9238 
9239 		default:
9240 			TCU_FAIL("Invalid enum");
9241 			break;
9242 		}
9243 	}
9244 	else
9245 	{
9246 		const std::string& fragment_shader_source =
9247 			this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification);
9248 		const std::string& vertex_shader_source =
9249 			this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification);
9250 
9251 		this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false);
9252 	}
9253 
9254 	/* We are now ready to verify whether the returned size is correct. */
9255 	unsigned char	  buffer[4]			 = { 0 };
9256 	glw::GLuint		   framebuffer_object_id = 0;
9257 	glw::GLuint		   routine_index		 = -1;
9258 	glw::GLuint		   routine_location		 = -1;
9259 	const glw::GLchar* routine_name			 = "original_routine";
9260 	glw::GLenum		   shader_type			 = 0;
9261 	glw::GLuint		   texture_object_id	 = 0;
9262 	glw::GLuint		   vao_id				 = 0;
9263 
9264 	switch (tested_shader_type)
9265 	{
9266 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9267 		shader_type = GL_FRAGMENT_SHADER;
9268 		break;
9269 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9270 		shader_type = GL_VERTEX_SHADER;
9271 		break;
9272 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9273 		shader_type = GL_COMPUTE_SHADER;
9274 		break;
9275 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9276 		shader_type = GL_GEOMETRY_SHADER;
9277 		break;
9278 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9279 		shader_type = GL_TESS_CONTROL_SHADER;
9280 		break;
9281 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9282 		shader_type = GL_TESS_EVALUATION_SHADER;
9283 		break;
9284 	default:
9285 		TCU_FAIL("Invalid shader type");
9286 		break;
9287 	}
9288 
9289 	if (false == use_original)
9290 	{
9291 		routine_name = "new_routine";
9292 	}
9293 
9294 	gl.useProgram(this->program_object_id);
9295 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed.");
9296 
9297 	/* Select subroutine */
9298 	routine_index = gl.getSubroutineIndex(this->program_object_id, shader_type, routine_name);
9299 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() failed.");
9300 
9301 	routine_location = gl.getSubroutineUniformLocation(this->program_object_id, shader_type, "routine");
9302 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() failed.");
9303 
9304 	if (0 != routine_location)
9305 	{
9306 		TCU_FAIL("Subroutine location is invalid");
9307 	}
9308 
9309 	gl.uniformSubroutinesuiv(shader_type, 1, &routine_index);
9310 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() failed.");
9311 
9312 	/* Prepre texture */
9313 	assert(0 == texture_object_id);
9314 	gl.genTextures(1, &texture_object_id);
9315 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed.");
9316 
9317 	gl.bindTexture(GL_TEXTURE_2D, texture_object_id);
9318 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed.");
9319 
9320 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
9321 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed.");
9322 
9323 	/* Prepare framebuffer */
9324 	assert(0 == framebuffer_object_id);
9325 	gl.genFramebuffers(1, &framebuffer_object_id);
9326 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed.");
9327 
9328 	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
9329 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed.");
9330 
9331 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0);
9332 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed.");
9333 
9334 	gl.viewport(0, 0, 1, 1);
9335 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed.");
9336 
9337 	/* Set VAO */
9338 	assert(0 == vao_id);
9339 	gl.genVertexArrays(1, &vao_id);
9340 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed.");
9341 
9342 	gl.bindVertexArray(vao_id);
9343 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed.");
9344 
9345 	switch (tested_shader_type)
9346 	{
9347 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
9348 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9349 		gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
9350 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9351 		break;
9352 
9353 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
9354 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9355 		/* Tesselation patch set up */
9356 		gl.patchParameteri(GL_PATCH_VERTICES, 1);
9357 		GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
9358 
9359 		gl.drawArrays(GL_PATCHES, 0, 1);
9360 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9361 		break;
9362 
9363 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9364 		gl.drawArrays(GL_POINTS, 0, 1);
9365 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed.");
9366 		break;
9367 
9368 	default:
9369 		TCU_FAIL("Invalid enum");
9370 		break;
9371 	}
9372 
9373 	/* Verify */
9374 	gl.readBuffer(GL_COLOR_ATTACHMENT0);
9375 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed.");
9376 
9377 	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
9378 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed.");
9379 
9380 	const bool result = ((buffer[0] != 255) == expect_invalid_result);
9381 
9382 	/* Delete generated objects. */
9383 	gl.useProgram(0);
9384 	gl.bindTexture(GL_TEXTURE_2D, 0);
9385 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
9386 	gl.bindVertexArray(0);
9387 
9388 	gl.deleteProgram(this->program_object_id);
9389 	this->program_object_id = 0;
9390 
9391 	gl.deleteTextures(1, &texture_object_id);
9392 	texture_object_id = 0;
9393 
9394 	gl.deleteFramebuffers(1, &framebuffer_object_id);
9395 	framebuffer_object_id = 0;
9396 
9397 	gl.deleteVertexArrays(1, &vao_id);
9398 	vao_id = 0;
9399 
9400 	GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects.");
9401 
9402 	if (!result)
9403 	{
9404 		TCU_FAIL("Invalid result was returned.");
9405 	}
9406 }
9407 
9408 /** Prepare shader
9409  *
9410  * @tparam API               Tested API descriptor
9411  *
9412  * @param tested_shader_type    The type of shader that is being tested
9413  * @param function_definition   Definition used to prepare shader
9414  * @param function_use          Use of definition
9415  * @param verification          Result verification
9416  **/
9417 template <class API>
prepare_compute_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)9418 std::string SubroutineFunctionCalls1<API>::prepare_compute_shader(
9419 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9420 	const std::string& function_use, const std::string& verification)
9421 {
9422 	std::string compute_shader_source;
9423 
9424 	if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type)
9425 	{
9426 		compute_shader_source = "writeonly uniform image2D uni_image;\n"
9427 								"\n";
9428 
9429 		/* User-defined function definition. */
9430 		compute_shader_source += function_definition;
9431 		compute_shader_source += "\n\n";
9432 
9433 		/* Main function definition. */
9434 		compute_shader_source += shader_start;
9435 		compute_shader_source += function_use;
9436 		compute_shader_source += "\n\n";
9437 		compute_shader_source += verification;
9438 		compute_shader_source += "\n\n";
9439 		compute_shader_source += "\n"
9440 								 "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"
9441 								 "}\n"
9442 								 "\n";
9443 	}
9444 
9445 	return compute_shader_source;
9446 }
9447 
9448 /** Prepare shader
9449  *
9450  * @tparam API               Tested API descriptor
9451  *
9452  * @param tested_shader_type    The type of shader that is being tested
9453  * @param function_definition   Definition used to prepare shader
9454  * @param function_use          Use of definition
9455  * @param verification          Result verification
9456  **/
9457 template <class API>
prepare_fragment_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)9458 std::string SubroutineFunctionCalls1<API>::prepare_fragment_shader(
9459 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9460 	const std::string& function_use, const std::string& verification)
9461 {
9462 	std::string fragment_shader_source;
9463 
9464 	switch (tested_shader_type)
9465 	{
9466 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9467 		break;
9468 
9469 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9470 		fragment_shader_source = "out vec4 colour;\n\n";
9471 
9472 		/* User-defined function definition. */
9473 		fragment_shader_source += function_definition;
9474 		fragment_shader_source += "\n\n";
9475 
9476 		/* Main function definition. */
9477 		fragment_shader_source += shader_start;
9478 		fragment_shader_source += function_use;
9479 		fragment_shader_source += "\n\n";
9480 		fragment_shader_source += verification;
9481 		fragment_shader_source += "\n\n";
9482 		fragment_shader_source += "    colour = vec4(result);\n";
9483 		fragment_shader_source += shader_end;
9484 		break;
9485 
9486 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9487 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9488 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: /* Fall through */
9489 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9490 		fragment_shader_source = "in float fs_result;\n\n"
9491 								 "out vec4 colour;\n\n"
9492 								 "void main()\n"
9493 								 "{\n"
9494 								 "    colour =  vec4(fs_result);\n"
9495 								 "}\n"
9496 								 "\n";
9497 		break;
9498 
9499 	default:
9500 		TCU_FAIL("Unrecognized shader object type.");
9501 		break;
9502 	}
9503 
9504 	return fragment_shader_source;
9505 }
9506 
9507 /** Prepare shader
9508  *
9509  * @tparam API               Tested API descriptor
9510  *
9511  * @param tested_shader_type    The type of shader that is being tested
9512  * @param function_definition   Definition used to prepare shader
9513  * @param function_use          Use of definition
9514  * @param verification          Result verification
9515  **/
9516 template <class API>
prepare_geometry_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)9517 std::string SubroutineFunctionCalls1<API>::prepare_geometry_shader(
9518 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9519 	const std::string& function_use, const std::string& verification)
9520 {
9521 	std::string geometry_shader_source;
9522 
9523 	switch (tested_shader_type)
9524 	{
9525 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9526 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */
9527 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9528 		break;
9529 
9530 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */
9531 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9532 		geometry_shader_source = "layout(points)                           in;\n"
9533 								 "layout(triangle_strip, max_vertices = 4) out;\n"
9534 								 "\n"
9535 								 "in  float tes_result[];\n"
9536 								 "out float fs_result;\n"
9537 								 "\n"
9538 								 "void main()\n"
9539 								 "{\n"
9540 								 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9541 								 "    fs_result    = tes_result[0];\n"
9542 								 "    EmitVertex();\n"
9543 								 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9544 								 "    fs_result    = tes_result[0];\n"
9545 								 "    EmitVertex();\n"
9546 								 "    gl_Position  = vec4(1, -1, 0, 1);\n"
9547 								 "    fs_result    = tes_result[0];\n"
9548 								 "    EmitVertex();\n"
9549 								 "    gl_Position  = vec4(1, 1, 0, 1);\n"
9550 								 "    fs_result    = tes_result[0];\n"
9551 								 "    EmitVertex();\n"
9552 								 "}\n";
9553 		break;
9554 
9555 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9556 		geometry_shader_source = "layout(points)                           in;\n"
9557 								 "layout(triangle_strip, max_vertices = 4) out;\n"
9558 								 "\n"
9559 								 "out float fs_result;\n"
9560 								 "\n";
9561 
9562 		/* User-defined function definition. */
9563 		geometry_shader_source += function_definition;
9564 		geometry_shader_source += "\n\n";
9565 
9566 		/* Main function definition. */
9567 		geometry_shader_source += shader_start;
9568 		geometry_shader_source += function_use;
9569 		geometry_shader_source += "\n\n";
9570 		geometry_shader_source += verification;
9571 		geometry_shader_source += "\n\n";
9572 		geometry_shader_source += "\n    gl_Position  = vec4(-1, -1, 0, 1);\n"
9573 								  "    fs_result    = result;\n"
9574 								  "    EmitVertex();\n"
9575 								  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9576 								  "    fs_result    = result;\n"
9577 								  "    EmitVertex();\n"
9578 								  "    gl_Position  = vec4(1, -1, 0, 1);\n"
9579 								  "    fs_result    = result;\n"
9580 								  "    EmitVertex();\n"
9581 								  "    gl_Position  = vec4(1, 1, 0, 1);\n"
9582 								  "    fs_result    = result;\n"
9583 								  "    EmitVertex();\n"
9584 								  "}\n";
9585 		break;
9586 
9587 	default:
9588 		TCU_FAIL("Unrecognized shader object type.");
9589 		break;
9590 	}
9591 
9592 	return geometry_shader_source;
9593 }
9594 
9595 /** Prepare shader
9596  *
9597  * @tparam API               Tested API descriptor
9598  *
9599  * @param tested_shader_type    The type of shader that is being tested
9600  * @param function_definition   Definition used to prepare shader
9601  * @param function_use          Use of definition
9602  * @param verification          Result verification
9603  **/
9604 template <class API>
prepare_tess_ctrl_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)9605 std::string SubroutineFunctionCalls1<API>::prepare_tess_ctrl_shader(
9606 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9607 	const std::string& function_use, const std::string& verification)
9608 {
9609 	std::string tess_ctrl_shader_source;
9610 
9611 	switch (tested_shader_type)
9612 	{
9613 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9614 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9615 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9616 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9617 		break;
9618 
9619 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9620 		tess_ctrl_shader_source = "layout(vertices = 1) out;\n"
9621 								  "\n"
9622 								  "out float tcs_result[];\n"
9623 								  "\n";
9624 
9625 		/* User-defined function definition. */
9626 		tess_ctrl_shader_source += function_definition;
9627 		tess_ctrl_shader_source += "\n\n";
9628 
9629 		/* Main function definition. */
9630 		tess_ctrl_shader_source += shader_start;
9631 		tess_ctrl_shader_source += function_use;
9632 		tess_ctrl_shader_source += "\n\n";
9633 		tess_ctrl_shader_source += verification;
9634 		tess_ctrl_shader_source += "\n\n";
9635 		tess_ctrl_shader_source += "    tcs_result[gl_InvocationID] = result;\n"
9636 								   "\n"
9637 								   "    gl_TessLevelOuter[0] = 1.0;\n"
9638 								   "    gl_TessLevelOuter[1] = 1.0;\n"
9639 								   "    gl_TessLevelOuter[2] = 1.0;\n"
9640 								   "    gl_TessLevelOuter[3] = 1.0;\n"
9641 								   "    gl_TessLevelInner[0] = 1.0;\n"
9642 								   "    gl_TessLevelInner[1] = 1.0;\n"
9643 								   "}\n";
9644 		break;
9645 
9646 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9647 		tess_ctrl_shader_source = default_tc_shader_source;
9648 		break;
9649 
9650 	default:
9651 		TCU_FAIL("Unrecognized shader object type.");
9652 		break;
9653 	}
9654 
9655 	return tess_ctrl_shader_source;
9656 }
9657 
9658 /** Prepare shader
9659  *
9660  * @tparam API               Tested API descriptor
9661  *
9662  * @param tested_shader_type    The type of shader that is being tested
9663  * @param function_definition   Definition used to prepare shader
9664  * @param function_use          Use of definition
9665  * @param verification          Result verification
9666  **/
9667 template <class API>
prepare_tess_eval_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)9668 std::string SubroutineFunctionCalls1<API>::prepare_tess_eval_shader(
9669 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9670 	const std::string& function_use, const std::string& verification)
9671 {
9672 	std::string tess_eval_shader_source;
9673 
9674 	switch (tested_shader_type)
9675 	{
9676 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9677 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9678 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9679 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9680 		break;
9681 
9682 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9683 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
9684 								  "\n"
9685 								  "in  float tcs_result[];\n"
9686 								  "out float tes_result;\n"
9687 								  "\n"
9688 								  "void main()\n"
9689 								  "{\n"
9690 								  "    tes_result = tcs_result[0];\n"
9691 								  "}\n";
9692 		break;
9693 
9694 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9695 		tess_eval_shader_source = "layout(isolines, point_mode) in;\n"
9696 								  "\n"
9697 								  "out float tes_result;\n"
9698 								  "\n";
9699 
9700 		/* User-defined function definition. */
9701 		tess_eval_shader_source += function_definition;
9702 		tess_eval_shader_source += "\n\n";
9703 
9704 		/* Main function definition. */
9705 		tess_eval_shader_source += shader_start;
9706 		tess_eval_shader_source += function_use;
9707 		tess_eval_shader_source += "\n\n";
9708 		tess_eval_shader_source += verification;
9709 		tess_eval_shader_source += "\n\n";
9710 		tess_eval_shader_source += "    tes_result = result;\n"
9711 								   "}\n";
9712 		break;
9713 
9714 	default:
9715 		TCU_FAIL("Unrecognized shader object type.");
9716 		break;
9717 	}
9718 
9719 	return tess_eval_shader_source;
9720 }
9721 
9722 /** Prepare shader
9723  *
9724  * @tparam API               Tested API descriptor
9725  *
9726  * @param tested_shader_type    The type of shader that is being tested
9727  * @param function_definition   Definition used to prepare shader
9728  * @param function_use          Use of definition
9729  * @param verification          Result verification
9730  **/
9731 template <class API>
prepare_vertex_shader(typename TestCaseBase<API>::TestShaderType tested_shader_type,const std::string & function_definition,const std::string & function_use,const std::string & verification)9732 std::string SubroutineFunctionCalls1<API>::prepare_vertex_shader(
9733 	typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition,
9734 	const std::string& function_use, const std::string& verification)
9735 {
9736 	std::string vertex_shader_source;
9737 
9738 	switch (tested_shader_type)
9739 	{
9740 	case TestCaseBase<API>::COMPUTE_SHADER_TYPE:
9741 		break;
9742 
9743 	case TestCaseBase<API>::FRAGMENT_SHADER_TYPE:
9744 		vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
9745 							   "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
9746 							   "                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
9747 							   "                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
9748 							   "                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n"
9749 							   "\n"
9750 							   "void main()\n"
9751 							   "{\n"
9752 							   "    gl_Position = vertex_positions[gl_VertexID];"
9753 							   "}\n\n";
9754 		break;
9755 
9756 	case TestCaseBase<API>::GEOMETRY_SHADER_TYPE:
9757 	case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE:
9758 	case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE:
9759 		vertex_shader_source = default_vertex_shader_source;
9760 		break;
9761 
9762 	case TestCaseBase<API>::VERTEX_SHADER_TYPE:
9763 		/* Vertex shader source. */
9764 		vertex_shader_source = "out float fs_result;\n\n";
9765 		vertex_shader_source += "/** GL_TRIANGLE_FAN-type quad vertex data. */\n"
9766 								"const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n"
9767 								"                                         vec4(-1.0, -1.0, 0.0, 1.0),\n"
9768 								"                                         vec4(-1.0,  1.0, 0.0, 1.0),\n"
9769 								"                                         vec4( 1.0,  1.0, 0.0, 1.0) );\n\n";
9770 
9771 		/* User-defined function definition. */
9772 		vertex_shader_source += function_definition;
9773 		vertex_shader_source += "\n\n";
9774 
9775 		/* Main function definition. */
9776 		vertex_shader_source += shader_start;
9777 		vertex_shader_source += function_use;
9778 		vertex_shader_source += "\n\n";
9779 		vertex_shader_source += verification;
9780 		vertex_shader_source += "\n\n";
9781 		vertex_shader_source += "    fs_result   = result;\n"
9782 								"    gl_Position = vertex_positions[gl_VertexID];\n";
9783 		vertex_shader_source += shader_end;
9784 		break;
9785 
9786 	default:
9787 		TCU_FAIL("Unrecognized shader object type.");
9788 		break;
9789 	}
9790 
9791 	return vertex_shader_source;
9792 }
9793 
9794 /* Generates the shader source code for the InteractionFunctionCalls2
9795  * array tests, and attempts to build and execute test program.
9796  *
9797  * @tparam API               Tested API descriptor
9798  *
9799  * @param tested_shader_type The type of shader that is being tested
9800  */
9801 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)9802 void SubroutineFunctionCalls2<API>::test_shader_compilation(
9803 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
9804 {
9805 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9806 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9807 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9808 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
9809 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
9810 
9811 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9812 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9813 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9814 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
9815 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
9816 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
9817 
9818 	const std::string iteration_loop_end = "                }\n"
9819 										   "            }\n"
9820 										   "        }\n"
9821 										   "    }\n";
9822 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
9823 											 "    {\n"
9824 											 "        for (uint b = 0u; b < 2u; b++)\n"
9825 											 "        {\n"
9826 											 "            for (uint c = 0u; c < 2u; c++)\n"
9827 											 "            {\n"
9828 											 "                for (uint d = 0u; d < 2u; d++)\n"
9829 											 "                {\n";
9830 	const std::string multiplier_array = "const int[] multiplier_array = int[]( 1,  2,  3,  4,  5,  6,  7,  8,\n"
9831 										 "                                     11, 12, 13, 14, 15, 16, 17, 18,\n"
9832 										 "                                     21, 22, 23, 24, 25, 26, 27, 28,\n"
9833 										 "                                     31, 32, 33, 34, 35, 36, 37, 38,\n"
9834 										 "                                     41, 42, 43, 44, 45, 46, 47, 48,\n"
9835 										 "                                     51, 52, 53, 54, 55, 56, 57, 58,\n"
9836 										 "                                     61, 62, 63, 64, 65, 66, 67, 68,\n"
9837 										 "                                     71, 72, 73, 74, 75, 76, 77, 78,\n"
9838 										 "                                     81, 82, 83, 84, 85, 86, 87, 88);\n";
9839 	const glcts::test_var_type* var_types_set = var_types_set_es;
9840 	size_t						num_var_types = num_var_types_es;
9841 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
9842 
9843 	if (API::USE_DOUBLE)
9844 	{
9845 		var_types_set = var_types_set_gl;
9846 		num_var_types = num_var_types_gl;
9847 	}
9848 
9849 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
9850 	{
9851 		_supported_variable_types_map_const_iterator var_iterator =
9852 			supported_variable_types_map.find(var_types_set[var_type_index]);
9853 
9854 		if (var_iterator != supported_variable_types_map.end())
9855 		{
9856 			std::string function_definition;
9857 			std::string function_use;
9858 			std::string verification;
9859 
9860 			function_definition += multiplier_array;
9861 
9862 			function_definition += "// Subroutine types\n"
9863 								   "subroutine void inout_routine_type(inout ";
9864 			function_definition += var_iterator->second.type;
9865 			function_definition += " inout_array[2][2][2][2]);\n\n"
9866 								   "// Subroutine definitions\n"
9867 								   "subroutine(inout_routine_type) void original_routine(inout ";
9868 			function_definition += var_iterator->second.type;
9869 			function_definition += " inout_array[2][2][2][2]) {\n"
9870 								   "    uint i = 0u;\n";
9871 			function_definition += iteration_loop_start;
9872 			function_definition += "                                   inout_array[a][b][c][d] *= " +
9873 								   var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n";
9874 			function_definition += "                                   i+= 1u;\n";
9875 			function_definition += iteration_loop_end;
9876 			function_definition += "}\n\n"
9877 								   "subroutine(inout_routine_type) void new_routine(inout ";
9878 			function_definition += var_iterator->second.type;
9879 			function_definition += " inout_array[2][2][2][2]) {\n"
9880 								   "    uint i = 0u;\n";
9881 			function_definition += iteration_loop_start;
9882 			function_definition += "                                   inout_array[a][b][c][d] /= " +
9883 								   var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n";
9884 			function_definition += "                                   i+= 1u;\n";
9885 			function_definition += iteration_loop_end;
9886 			function_definition += "}\n\n"
9887 								   "// Subroutine uniform\n"
9888 								   "subroutine uniform inout_routine_type routine;\n";
9889 
9890 			function_use += "    float result = 1.0;\n";
9891 			function_use += "    uint iterator = 0u;\n";
9892 			function_use += "    " + var_iterator->second.type + " my_array[2][2][2][2];\n";
9893 			function_use += iteration_loop_start;
9894 			function_use += "                                   my_array[a][b][c][d] = " +
9895 							var_iterator->second.variable_type_initializer2 + ";\n";
9896 			function_use += iteration_loop_end;
9897 			function_use += "    routine(my_array);";
9898 
9899 			verification += iteration_loop_start;
9900 			verification += "                                   if (my_array[a][b][c][d] " +
9901 							var_iterator->second.specific_element + "!= " + var_iterator->second.iterator_type +
9902 							"(multiplier_array[iterator % 64u]))\n"
9903 							"                                   {\n"
9904 							"                                       result = 0.0;\n"
9905 							"                                   }\n"
9906 							"                                   iterator += 1u;\n";
9907 			verification += iteration_loop_end;
9908 
9909 			if (false == test_compute)
9910 			{
9911 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
9912 										true);
9913 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
9914 										false);
9915 			}
9916 			else
9917 			{
9918 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
9919 											true);
9920 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
9921 											false);
9922 			}
9923 
9924 			/* Deallocate any resources used. */
9925 			this->delete_objects();
9926 		} /* if var_type iterator found */
9927 		else
9928 		{
9929 			TCU_FAIL("Type not found.");
9930 		}
9931 	} /* for (int var_type_index = 0; ...) */
9932 }
9933 
9934 /* Generates the shader source code for the SubroutineArgumentAliasing1
9935  * array tests, attempts to build and execute test program
9936  *
9937  * @tparam API               Tested API descriptor
9938  *
9939  * @param tested_shader_type The type of shader that is being tested
9940  */
9941 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)9942 void SubroutineArgumentAliasing1<API>::test_shader_compilation(
9943 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
9944 {
9945 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9946 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9947 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9948 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
9949 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
9950 
9951 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
9952 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
9953 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
9954 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
9955 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
9956 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
9957 
9958 	const std::string iteration_loop_end = "                }\n"
9959 										   "            }\n"
9960 										   "        }\n"
9961 										   "    }\n";
9962 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
9963 											 "    {\n"
9964 											 "        for (uint b = 0u; b < 2u; b++)\n"
9965 											 "        {\n"
9966 											 "            for (uint c = 0u; c < 2u; c++)\n"
9967 											 "            {\n"
9968 											 "                for (uint d = 0u; d < 2u; d++)\n"
9969 											 "                {\n";
9970 	const glcts::test_var_type* var_types_set = var_types_set_es;
9971 	size_t						num_var_types = num_var_types_es;
9972 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
9973 
9974 	if (API::USE_DOUBLE)
9975 	{
9976 		var_types_set = var_types_set_gl;
9977 		num_var_types = num_var_types_gl;
9978 	}
9979 
9980 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
9981 	{
9982 		_supported_variable_types_map_const_iterator var_iterator =
9983 			supported_variable_types_map.find(var_types_set[var_type_index]);
9984 
9985 		if (var_iterator != supported_variable_types_map.end())
9986 		{
9987 			std::string function_definition;
9988 			std::string function_use;
9989 			std::string verification;
9990 
9991 			function_definition += "// Subroutine types\n"
9992 								   "subroutine bool in_routine_type(";
9993 			function_definition += var_iterator->second.type;
9994 			function_definition += " x[2][2][2][2], ";
9995 			function_definition += var_iterator->second.type;
9996 			function_definition += " y[2][2][2][2]);\n\n"
9997 								   "// Subroutine definitions\n"
9998 								   "subroutine(in_routine_type) bool original_routine(";
9999 			function_definition += var_iterator->second.type;
10000 			function_definition += " x[2][2][2][2], ";
10001 			function_definition += var_iterator->second.type;
10002 			function_definition += " y[2][2][2][2])\n{\n";
10003 			function_definition += iteration_loop_start;
10004 			function_definition +=
10005 				"                                   x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10006 			function_definition += iteration_loop_end;
10007 			function_definition += "\n";
10008 			function_definition += iteration_loop_start;
10009 			function_definition += "                                   if(y[a][b][c][d]";
10010 			if (var_iterator->second.type == "mat4") // mat4 comparison
10011 			{
10012 				function_definition += "[0][0]";
10013 				function_definition += " != float";
10014 			}
10015 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10016 			{
10017 				function_definition += "[0][0]";
10018 				function_definition += " != double";
10019 			}
10020 			else
10021 			{
10022 				function_definition += " != ";
10023 				function_definition += var_iterator->second.type;
10024 			}
10025 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10026 			function_definition += iteration_loop_end;
10027 			function_definition += "\n    return true;\n";
10028 			function_definition += "}\n\n"
10029 								   "subroutine(in_routine_type) bool new_routine(";
10030 			function_definition += var_iterator->second.type;
10031 			function_definition += " x[2][2][2][2], ";
10032 			function_definition += var_iterator->second.type;
10033 			function_definition += " y[2][2][2][2])\n{\n";
10034 			function_definition += iteration_loop_start;
10035 			function_definition +=
10036 				"                                   y[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10037 			function_definition += iteration_loop_end;
10038 			function_definition += "\n";
10039 			function_definition += iteration_loop_start;
10040 			function_definition += "                                   if(x[a][b][c][d]";
10041 			if (var_iterator->second.type == "mat4") // mat4 comparison
10042 			{
10043 				function_definition += "[0][0]";
10044 				function_definition += " != float";
10045 			}
10046 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10047 			{
10048 				function_definition += "[0][0]";
10049 				function_definition += " != double";
10050 			}
10051 			else
10052 			{
10053 				function_definition += " != ";
10054 				function_definition += var_iterator->second.type;
10055 			}
10056 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10057 			function_definition += iteration_loop_end;
10058 			function_definition += "\n    return true;\n";
10059 			function_definition += "}\n\n"
10060 								   "// Subroutine uniform\n"
10061 								   "subroutine uniform in_routine_type routine;\n";
10062 
10063 			function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10064 			function_use += iteration_loop_start;
10065 			function_use += "                                   z[a][b][c][d] = ";
10066 			function_use += var_iterator->second.type;
10067 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10068 			function_use += iteration_loop_end;
10069 
10070 			verification = "    float result = 0.0;\n"
10071 						   "    if(routine(z, z) == true)\n"
10072 						   "    {\n"
10073 						   "        result = 1.0;\n"
10074 						   "    }\n"
10075 						   "    else\n"
10076 						   "    {\n"
10077 						   "        result = 0.5;\n"
10078 						   "    }\n";
10079 
10080 			if (false == test_compute)
10081 			{
10082 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10083 										false);
10084 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10085 										false);
10086 			}
10087 			else
10088 			{
10089 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10090 											false);
10091 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10092 											false);
10093 			}
10094 
10095 			/* Deallocate any resources used. */
10096 			this->delete_objects();
10097 		} /* if var_type iterator found */
10098 		else
10099 		{
10100 			TCU_FAIL("Type not found.");
10101 		}
10102 	} /* for (int var_type_index = 0; ...) */
10103 }
10104 
10105 /* Generates the shader source code for the SubroutineArgumentAliasing1
10106  * array tests, attempts to build and execute test program
10107  *
10108  * @tparam API               Tested API descriptor
10109  *
10110  * @param tested_shader_type The type of shader that is being tested
10111  */
10112 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)10113 void SubroutineArgumentAliasing2<API>::test_shader_compilation(
10114 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
10115 {
10116 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10117 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10118 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10119 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
10120 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
10121 
10122 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10123 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10124 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10125 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
10126 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
10127 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
10128 
10129 	const std::string iteration_loop_end = "                }\n"
10130 										   "            }\n"
10131 										   "        }\n"
10132 										   "    }\n";
10133 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
10134 											 "    {\n"
10135 											 "        for (uint b = 0u; b < 2u; b++)\n"
10136 											 "        {\n"
10137 											 "            for (uint c = 0u; c < 2u; c++)\n"
10138 											 "            {\n"
10139 											 "                for (uint d = 0u; d < 2u; d++)\n"
10140 											 "                {\n";
10141 	const glcts::test_var_type* var_types_set = var_types_set_es;
10142 	size_t						num_var_types = num_var_types_es;
10143 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
10144 
10145 	if (API::USE_DOUBLE)
10146 	{
10147 		var_types_set = var_types_set_gl;
10148 		num_var_types = num_var_types_gl;
10149 	}
10150 
10151 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
10152 	{
10153 		_supported_variable_types_map_const_iterator var_iterator =
10154 			supported_variable_types_map.find(var_types_set[var_type_index]);
10155 
10156 		if (var_iterator != supported_variable_types_map.end())
10157 		{
10158 			std::string function_definition;
10159 			std::string function_use;
10160 			std::string verification;
10161 
10162 			function_definition += "// Subroutine types\n"
10163 								   "subroutine bool inout_routine_type(inout ";
10164 			function_definition += var_iterator->second.type;
10165 			function_definition += " x[2][2][2][2], inout ";
10166 			function_definition += var_iterator->second.type;
10167 			function_definition += " y[2][2][2][2]);\n\n"
10168 								   "// Subroutine definitions\n"
10169 								   "subroutine(inout_routine_type) bool original_routine(inout ";
10170 			function_definition += var_iterator->second.type;
10171 			function_definition += " x[2][2][2][2], inout ";
10172 			function_definition += var_iterator->second.type;
10173 			function_definition += " y[2][2][2][2])\n{\n";
10174 			function_definition += iteration_loop_start;
10175 			function_definition +=
10176 				"                                   x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10177 			function_definition += iteration_loop_end;
10178 			function_definition += "\n";
10179 			function_definition += iteration_loop_start;
10180 			function_definition += "                                   if(y[a][b][c][d]";
10181 			if (var_iterator->second.type == "mat4") // mat4 comparison
10182 			{
10183 				function_definition += "[0][0]";
10184 				function_definition += " != float";
10185 			}
10186 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10187 			{
10188 				function_definition += "[0][0]";
10189 				function_definition += " != double";
10190 			}
10191 			else
10192 			{
10193 				function_definition += " != ";
10194 				function_definition += var_iterator->second.type;
10195 			}
10196 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10197 			function_definition += iteration_loop_end;
10198 			function_definition += "\n    return true;\n";
10199 			function_definition += "}\n\n"
10200 								   "subroutine(inout_routine_type) bool new_routine(inout ";
10201 			function_definition += var_iterator->second.type;
10202 			function_definition += " x[2][2][2][2], inout ";
10203 			function_definition += var_iterator->second.type;
10204 			function_definition += " y[2][2][2][2])\n{\n";
10205 			function_definition += iteration_loop_start;
10206 			function_definition +=
10207 				"                                   y[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10208 			function_definition += iteration_loop_end;
10209 			function_definition += "\n";
10210 			function_definition += iteration_loop_start;
10211 			function_definition += "                                   if(x[a][b][c][d]";
10212 			if (var_iterator->second.type == "mat4") // mat4 comparison
10213 			{
10214 				function_definition += "[0][0]";
10215 				function_definition += " != float";
10216 			}
10217 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10218 			{
10219 				function_definition += "[0][0]";
10220 				function_definition += " != double";
10221 			}
10222 			else
10223 			{
10224 				function_definition += " != ";
10225 				function_definition += var_iterator->second.type;
10226 			}
10227 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10228 			function_definition += iteration_loop_end;
10229 			function_definition += "\n    return true;\n";
10230 			function_definition += "}\n\n"
10231 								   "// Subroutine uniform\n"
10232 								   "subroutine uniform inout_routine_type routine;\n";
10233 
10234 			function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10235 			function_use += iteration_loop_start;
10236 			function_use += "                                   z[a][b][c][d] = ";
10237 			function_use += var_iterator->second.type;
10238 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10239 			function_use += iteration_loop_end;
10240 
10241 			verification = "    float result = 0.0;\n"
10242 						   "    if(routine(z, z) == true)\n"
10243 						   "    {\n"
10244 						   "        result = 1.0;\n"
10245 						   "    }\n"
10246 						   "    else\n"
10247 						   "    {\n"
10248 						   "        result = 0.5;\n"
10249 						   "    }\n";
10250 
10251 			if (false == test_compute)
10252 			{
10253 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10254 										false);
10255 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10256 										false);
10257 			}
10258 			else
10259 			{
10260 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10261 											false);
10262 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10263 											false);
10264 			}
10265 
10266 			/* Deallocate any resources used. */
10267 			this->delete_objects();
10268 		} /* if var_type iterator found */
10269 		else
10270 		{
10271 			TCU_FAIL("Type not found.");
10272 		}
10273 	} /* for (int var_type_index = 0; ...) */
10274 }
10275 
10276 /* Generates the shader source code for the SubroutineArgumentAliasing1
10277  * array tests, attempts to build and execute test program
10278  *
10279  * @tparam API               Tested API descriptor
10280  *
10281  * @param tested_shader_type The type of shader that is being tested
10282  */
10283 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)10284 void SubroutineArgumentAliasing3<API>::test_shader_compilation(
10285 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
10286 {
10287 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10288 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10289 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10290 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
10291 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
10292 
10293 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10294 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10295 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10296 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
10297 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
10298 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
10299 
10300 	const std::string iteration_loop_end = "                }\n"
10301 										   "            }\n"
10302 										   "        }\n"
10303 										   "    }\n";
10304 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
10305 											 "    {\n"
10306 											 "        for (uint b = 0u; b < 2u; b++)\n"
10307 											 "        {\n"
10308 											 "            for (uint c = 0u; c < 2u; c++)\n"
10309 											 "            {\n"
10310 											 "                for (uint d = 0u; d < 2u; d++)\n"
10311 											 "                {\n";
10312 	const glcts::test_var_type* var_types_set = var_types_set_es;
10313 	size_t						num_var_types = num_var_types_es;
10314 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
10315 
10316 	if (API::USE_DOUBLE)
10317 	{
10318 		var_types_set = var_types_set_gl;
10319 		num_var_types = num_var_types_gl;
10320 	}
10321 
10322 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
10323 	{
10324 		_supported_variable_types_map_const_iterator var_iterator =
10325 			supported_variable_types_map.find(var_types_set[var_type_index]);
10326 
10327 		if (var_iterator != supported_variable_types_map.end())
10328 		{
10329 			std::string function_definition;
10330 			std::string function_use;
10331 			std::string verification;
10332 
10333 			function_definition += "// Subroutine types\n"
10334 								   "subroutine bool out_routine_type(out ";
10335 			function_definition += var_iterator->second.type;
10336 			function_definition += " x[2][2][2][2], ";
10337 			function_definition += var_iterator->second.type;
10338 			function_definition += " y[2][2][2][2]);\n\n"
10339 								   "// Subroutine definitions\n"
10340 								   "subroutine(out_routine_type) bool original_routine(out ";
10341 			function_definition += var_iterator->second.type;
10342 			function_definition += " x[2][2][2][2], ";
10343 			function_definition += var_iterator->second.type;
10344 			function_definition += " y[2][2][2][2])\n{\n";
10345 			function_definition += iteration_loop_start;
10346 			function_definition +=
10347 				"                                   x[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10348 			function_definition += iteration_loop_end;
10349 			function_definition += "\n";
10350 			function_definition += iteration_loop_start;
10351 			function_definition += "                                   if(y[a][b][c][d]";
10352 			if (var_iterator->second.type == "mat4") // mat4 comparison
10353 			{
10354 				function_definition += "[0][0]";
10355 				function_definition += " != float";
10356 			}
10357 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10358 			{
10359 				function_definition += "[0][0]";
10360 				function_definition += " != double";
10361 			}
10362 			else
10363 			{
10364 				function_definition += " != ";
10365 				function_definition += var_iterator->second.type;
10366 			}
10367 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10368 			function_definition += iteration_loop_end;
10369 			function_definition += "\n    return true;\n";
10370 			function_definition += "}\n\n"
10371 								   "subroutine(out_routine_type) bool new_routine(out ";
10372 			function_definition += var_iterator->second.type;
10373 			function_definition += " x[2][2][2][2], ";
10374 			function_definition += var_iterator->second.type;
10375 			function_definition += " y[2][2][2][2])\n{\n";
10376 			function_definition += iteration_loop_start;
10377 			function_definition +=
10378 				"                                   x[a][b][c][d] = " + var_iterator->second.type + "(321);\n";
10379 			function_definition += iteration_loop_end;
10380 			function_definition += "\n";
10381 			function_definition += iteration_loop_start;
10382 			function_definition += "                                   if(y[a][b][c][d]";
10383 			if (var_iterator->second.type == "mat4") // mat4 comparison
10384 			{
10385 				function_definition += "[0][0]";
10386 				function_definition += " != float";
10387 			}
10388 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10389 			{
10390 				function_definition += "[0][0]";
10391 				function_definition += " != double";
10392 			}
10393 			else
10394 			{
10395 				function_definition += " != ";
10396 				function_definition += var_iterator->second.type;
10397 			}
10398 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10399 			function_definition += iteration_loop_end;
10400 			function_definition += "\n    return true;\n";
10401 			function_definition += "}\n\n"
10402 								   "// Subroutine uniform\n"
10403 								   "subroutine uniform out_routine_type routine;\n";
10404 
10405 			function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10406 			function_use += iteration_loop_start;
10407 			function_use += "                                   z[a][b][c][d] = ";
10408 			function_use += var_iterator->second.type;
10409 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10410 			function_use += iteration_loop_end;
10411 
10412 			verification = "    float result = 0.0;\n"
10413 						   "    if(routine(z, z) == true)\n"
10414 						   "    {\n"
10415 						   "        result = 1.0;\n"
10416 						   "    }\n"
10417 						   "    else\n"
10418 						   "    {\n"
10419 						   "        result = 0.5;\n"
10420 						   "    }\n";
10421 
10422 			if (false == test_compute)
10423 			{
10424 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10425 										false);
10426 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10427 										false);
10428 			}
10429 			else
10430 			{
10431 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10432 											false);
10433 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10434 											false);
10435 			}
10436 
10437 			/* Deallocate any resources used. */
10438 			this->delete_objects();
10439 		} /* if var_type iterator found */
10440 		else
10441 		{
10442 			TCU_FAIL("Type not found.");
10443 		}
10444 	} /* for (int var_type_index = 0; ...) */
10445 }
10446 
10447 /* Generates the shader source code for the SubroutineArgumentAliasing1
10448  * array tests, attempts to build and execute test program
10449  *
10450  * @tparam API               Tested API descriptor
10451  *
10452  * @param tested_shader_type The type of shader that is being tested
10453  */
10454 template <class API>
test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type)10455 void SubroutineArgumentAliasing4<API>::test_shader_compilation(
10456 	typename TestCaseBase<API>::TestShaderType tested_shader_type)
10457 {
10458 	static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10459 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10460 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10461 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4 };
10462 	static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]);
10463 
10464 	static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT,   VAR_TYPE_FLOAT, VAR_TYPE_IVEC2,
10465 															 VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2,
10466 															 VAR_TYPE_VEC3,  VAR_TYPE_VEC4,  VAR_TYPE_MAT2,
10467 															 VAR_TYPE_MAT3,  VAR_TYPE_MAT4,  VAR_TYPE_DOUBLE,
10468 															 VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 };
10469 	static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]);
10470 
10471 	const std::string iteration_loop_end = "                }\n"
10472 										   "            }\n"
10473 										   "        }\n"
10474 										   "    }\n";
10475 	const std::string iteration_loop_start = "    for (uint a = 0u; a < 2u; a++)\n"
10476 											 "    {\n"
10477 											 "        for (uint b = 0u; b < 2u; b++)\n"
10478 											 "        {\n"
10479 											 "            for (uint c = 0u; c < 2u; c++)\n"
10480 											 "            {\n"
10481 											 "                for (uint d = 0u; d < 2u; d++)\n"
10482 											 "                {\n";
10483 	const glcts::test_var_type* var_types_set = var_types_set_es;
10484 	size_t						num_var_types = num_var_types_es;
10485 	const bool					test_compute  = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type);
10486 
10487 	if (API::USE_DOUBLE)
10488 	{
10489 		var_types_set = var_types_set_gl;
10490 		num_var_types = num_var_types_gl;
10491 	}
10492 
10493 	for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++)
10494 	{
10495 		_supported_variable_types_map_const_iterator var_iterator =
10496 			supported_variable_types_map.find(var_types_set[var_type_index]);
10497 
10498 		if (var_iterator != supported_variable_types_map.end())
10499 		{
10500 			std::string function_definition;
10501 			std::string function_use;
10502 			std::string verification;
10503 
10504 			function_definition += "// Subroutine types\n"
10505 								   "subroutine bool out_routine_type(";
10506 			function_definition += var_iterator->second.type;
10507 			function_definition += " x[2][2][2][2], out ";
10508 			function_definition += var_iterator->second.type;
10509 			function_definition += " y[2][2][2][2]);\n\n"
10510 								   "// Subroutine definitions\n"
10511 								   "subroutine(out_routine_type) bool original_routine(";
10512 			function_definition += var_iterator->second.type;
10513 			function_definition += " x[2][2][2][2], out ";
10514 			function_definition += var_iterator->second.type;
10515 			function_definition += " y[2][2][2][2])\n{\n";
10516 			function_definition += iteration_loop_start;
10517 			function_definition +=
10518 				"                                   y[a][b][c][d] = " + var_iterator->second.type + "(123);\n";
10519 			function_definition += iteration_loop_end;
10520 			function_definition += "\n";
10521 			function_definition += iteration_loop_start;
10522 			function_definition += "                                   if(x[a][b][c][d]";
10523 			if (var_iterator->second.type == "mat4") // mat4 comparison
10524 			{
10525 				function_definition += "[0][0]";
10526 				function_definition += " != float";
10527 			}
10528 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10529 			{
10530 				function_definition += "[0][0]";
10531 				function_definition += " != double";
10532 			}
10533 			else
10534 			{
10535 				function_definition += " != ";
10536 				function_definition += var_iterator->second.type;
10537 			}
10538 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10539 			function_definition += iteration_loop_end;
10540 			function_definition += "\n    return true;\n";
10541 			function_definition += "}\n\n"
10542 								   "subroutine(out_routine_type) bool new_routine(";
10543 			function_definition += var_iterator->second.type;
10544 			function_definition += " x[2][2][2][2], out ";
10545 			function_definition += var_iterator->second.type;
10546 			function_definition += " y[2][2][2][2])\n{\n";
10547 			function_definition += iteration_loop_start;
10548 			function_definition +=
10549 				"                                   y[a][b][c][d] = " + var_iterator->second.type + "(321);\n";
10550 			function_definition += iteration_loop_end;
10551 			function_definition += "\n";
10552 			function_definition += iteration_loop_start;
10553 			function_definition += "                                   if(x[a][b][c][d]";
10554 			if (var_iterator->second.type == "mat4") // mat4 comparison
10555 			{
10556 				function_definition += "[0][0]";
10557 				function_definition += " != float";
10558 			}
10559 			else if (var_iterator->second.type == "dmat4") // dmat4 comparison
10560 			{
10561 				function_definition += "[0][0]";
10562 				function_definition += " != double";
10563 			}
10564 			else
10565 			{
10566 				function_definition += " != ";
10567 				function_definition += var_iterator->second.type;
10568 			}
10569 			function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n";
10570 			function_definition += iteration_loop_end;
10571 			function_definition += "\n    return true;\n";
10572 			function_definition += "}\n\n"
10573 								   "// Subroutine uniform\n"
10574 								   "subroutine uniform out_routine_type routine;\n";
10575 
10576 			function_use += "    " + var_iterator->second.type + " z[2][2][2][2];\n";
10577 			function_use += iteration_loop_start;
10578 			function_use += "                                   z[a][b][c][d] = ";
10579 			function_use += var_iterator->second.type;
10580 			function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n";
10581 			function_use += iteration_loop_end;
10582 
10583 			verification = "    float result = 0.0;\n"
10584 						   "    if(routine(z, z) == true)\n"
10585 						   "    {\n"
10586 						   "        result = 1.0;\n"
10587 						   "    }\n"
10588 						   "    else\n"
10589 						   "    {\n"
10590 						   "        result = 0.5;\n"
10591 						   "    }\n";
10592 
10593 			if (false == test_compute)
10594 			{
10595 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false,
10596 										false);
10597 				this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true,
10598 										false);
10599 			}
10600 			else
10601 			{
10602 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false,
10603 											false);
10604 				this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true,
10605 											false);
10606 			}
10607 
10608 			/* Deallocate any resources used. */
10609 			this->delete_objects();
10610 		} /* if var_type iterator found */
10611 		else
10612 		{
10613 			TCU_FAIL("Type not found.");
10614 		}
10615 	} /* for (int var_type_index = 0; ...) */
10616 }
10617 
10618 /** Instantiates all tests and adds them as children to the node
10619  *
10620  * @tparam API    Tested API descriptor
10621  *
10622  * @param context CTS context
10623  **/
10624 template <class API>
initTests(TestCaseGroup & group,glcts::Context & context)10625 void initTests(TestCaseGroup& group, glcts::Context& context)
10626 {
10627 	// Set up the map
10628 	ArraysOfArrays::initializeMap<API>();
10629 
10630 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsPrimitive<API>(context));
10631 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes1<API>(context));
10632 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes2<API>(context));
10633 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes3<API>(context));
10634 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes4<API>(context));
10635 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle1<API>(context));
10636 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle2<API>(context));
10637 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle3<API>(context));
10638 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle4<API>(context));
10639 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle5<API>(context));
10640 	group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsFunctionParams<API>(context));
10641 	group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes1<API>(context));
10642 	group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes2<API>(context));
10643 	group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes3<API>(context));
10644 	group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes4<API>(context));
10645 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructors1<API>(context));
10646 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructors2<API>(context));
10647 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedConstructors<API>(context));
10648 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConst<API>(context));
10649 
10650 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors1<API>(context));
10651 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors2<API>(context));
10652 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors3<API>(context));
10653 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors4<API>(context));
10654 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructorSizing1<API>(context));
10655 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructorSizing2<API>(context));
10656 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclStructConstructors<API>(context));
10657 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays1<API>(context));
10658 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays2<API>(context));
10659 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays3<API>(context));
10660 	group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays4<API>(context));
10661 	group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment1<API>(context));
10662 	group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment2<API>(context));
10663 	group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment3<API>(context));
10664 	group.addChild(new glcts::ArraysOfArrays::ExpressionsTypeRestrictions1<API>(context));
10665 	group.addChild(new glcts::ArraysOfArrays::ExpressionsTypeRestrictions2<API>(context));
10666 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar1<API>(context));
10667 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar2<API>(context));
10668 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar3<API>(context));
10669 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar4<API>(context));
10670 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray1<API>(context));
10671 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray2<API>(context));
10672 	group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray3<API>(context));
10673 	group.addChild(new glcts::ArraysOfArrays::ExpressionsDynamicIndexing1<API>(context));
10674 	group.addChild(new glcts::ArraysOfArrays::ExpressionsDynamicIndexing2<API>(context));
10675 	group.addChild(new glcts::ArraysOfArrays::ExpressionsEquality1<API>(context));
10676 	group.addChild(new glcts::ArraysOfArrays::ExpressionsEquality2<API>(context));
10677 	group.addChild(new glcts::ArraysOfArrays::ExpressionsLength1<API>(context));
10678 	group.addChild(new glcts::ArraysOfArrays::ExpressionsLength2<API>(context));
10679 	group.addChild(new glcts::ArraysOfArrays::ExpressionsLength3<API>(context));
10680 	group.addChild(new glcts::ArraysOfArrays::ExpressionsInvalid1<API>(context));
10681 	group.addChild(new glcts::ArraysOfArrays::ExpressionsInvalid2<API>(context));
10682 
10683 	group.addChild(new glcts::ArraysOfArrays::InteractionFunctionCalls1<API>(context));
10684 	group.addChild(new glcts::ArraysOfArrays::InteractionFunctionCalls2<API>(context));
10685 	group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing1<API>(context));
10686 	group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing2<API>(context));
10687 	group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing3<API>(context));
10688 	group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing4<API>(context));
10689 	group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing5<API>(context));
10690 	group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing6<API>(context));
10691 
10692 	group.addChild(new glcts::ArraysOfArrays::InteractionUniforms1<API>(context));
10693 	group.addChild(new glcts::ArraysOfArrays::InteractionUniforms2<API>(context));
10694 	group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers1<API>(context));
10695 	group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers2<API>(context));
10696 	group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers3<API>(context));
10697 	group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays1<API>(context));
10698 	group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays2<API>(context));
10699 	group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays3<API>(context));
10700 	group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays4<API>(context));
10701 
10702 	if (API::USE_STORAGE_BLOCK)
10703 	{
10704 		group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers1<API>(context));
10705 		group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers2<API>(context));
10706 		group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers3<API>(context));
10707 	}
10708 
10709 	if (API::USE_ATOMIC)
10710 	{
10711 		group.addChild(new glcts::ArraysOfArrays::AtomicDeclarationTest<API>(context));
10712 		group.addChild(new glcts::ArraysOfArrays::AtomicUsageTest<API>(context));
10713 	}
10714 
10715 	if (API::USE_SUBROUTINE)
10716 	{
10717 		group.addChild(new glcts::ArraysOfArrays::SubroutineFunctionCalls1<API>(context));
10718 		group.addChild(new glcts::ArraysOfArrays::SubroutineFunctionCalls2<API>(context));
10719 		group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing1<API>(context));
10720 		group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing2<API>(context));
10721 		group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing3<API>(context));
10722 		group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing4<API>(context));
10723 	}
10724 }
10725 } /* namespace ArraysOfArrays */
10726 
10727 /** Constructor
10728  *
10729  * @param context CTS context
10730  **/
ArrayOfArraysTestGroup(Context & context)10731 ArrayOfArraysTestGroup::ArrayOfArraysTestGroup(Context& context)
10732 	: TestCaseGroup(context, "arrays_of_arrays", "Groups all tests that verify 'arrays of arrays' functionality.")
10733 {
10734 	/* Left blank on purpose */
10735 }
10736 
10737 /* Instantiates all tests and adds them as children to the node */
init(void)10738 void ArrayOfArraysTestGroup::init(void)
10739 {
10740 	ArraysOfArrays::initTests<ArraysOfArrays::Interface::ES>(*this, m_context);
10741 }
10742 
10743 /** Constructor
10744  *
10745  * @param context CTS context
10746  **/
ArrayOfArraysTestGroupGL(Context & context)10747 ArrayOfArraysTestGroupGL::ArrayOfArraysTestGroupGL(Context& context)
10748 	: TestCaseGroup(context, "arrays_of_arrays_gl", "Groups all tests that verify 'arrays of arrays' functionality.")
10749 {
10750 	/* Left blank on purpose */
10751 }
10752 
10753 /* Instantiates all tests and adds them as children to the node */
init(void)10754 void ArrayOfArraysTestGroupGL::init(void)
10755 {
10756 	ArraysOfArrays::initTests<ArraysOfArrays::Interface::GL>(*this, m_context);
10757 }
10758 } /* namespace glcts */
10759