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