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