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