xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cGPUShaderFP64Tests.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GL4CGPUSHADERFP64TESTS_HPP
2 #define _GL4CGPUSHADERFP64TESTS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2014-2016 The Khronos Group Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */ /*!
22  * \file
23  * \brief
24  */ /*-------------------------------------------------------------------*/
25 
26 /**
27  * \file  gl4cGPUShaderFP64Tests.hpp
28  * \brief Declares test classes for "GPU Shader FP64" functionality.
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "glcTestCase.hpp"
32 #include "glwDefs.hpp"
33 #include "glwEnums.hpp"
34 #include "tcuDefs.hpp"
35 #include "tcuVector.hpp"
36 #include <queue>
37 
38 namespace gl4cts
39 {
40 class Utils
41 {
42 public:
43     /* Public type definitions */
44 
45     /** Store information about program object
46      *
47      **/
48     struct programInfo
49     {
50         programInfo(deqp::Context &context);
51         ~programInfo();
52 
53         void build(const glw::GLchar *compute_shader_code, const glw::GLchar *fragment_shader_code,
54                    const glw::GLchar *geometry_shader_code, const glw::GLchar *tesselation_control_shader_code,
55                    const glw::GLchar *tesselation_evaluation_shader_code, const glw::GLchar *vertex_shader_code,
56                    const glw::GLchar *const *varying_names, glw::GLuint n_varying_names);
57 
58         void compile(glw::GLuint shader_id, const glw::GLchar *shader_code) const;
59 
60         void link() const;
61 
62         static const glw::GLenum ARB_COMPUTE_SHADER;
63 
64         deqp::Context &m_context;
65 
66         glw::GLuint m_compute_shader_id;
67         glw::GLuint m_fragment_shader_id;
68         glw::GLuint m_geometry_shader_id;
69         glw::GLuint m_program_object_id;
70         glw::GLuint m_tesselation_control_shader_id;
71         glw::GLuint m_tesselation_evaluation_shader_id;
72         glw::GLuint m_vertex_shader_id;
73     };
74 
75     /* Defines GLSL variable type */
76     enum _variable_type
77     {
78         VARIABLE_TYPE_BOOL,
79         VARIABLE_TYPE_BVEC2,
80         VARIABLE_TYPE_BVEC3,
81         VARIABLE_TYPE_BVEC4,
82         VARIABLE_TYPE_DOUBLE,
83         VARIABLE_TYPE_DMAT2,
84         VARIABLE_TYPE_DMAT2X3,
85         VARIABLE_TYPE_DMAT2X4,
86         VARIABLE_TYPE_DMAT3,
87         VARIABLE_TYPE_DMAT3X2,
88         VARIABLE_TYPE_DMAT3X4,
89         VARIABLE_TYPE_DMAT4,
90         VARIABLE_TYPE_DMAT4X2,
91         VARIABLE_TYPE_DMAT4X3,
92         VARIABLE_TYPE_DVEC2,
93         VARIABLE_TYPE_DVEC3,
94         VARIABLE_TYPE_DVEC4,
95         VARIABLE_TYPE_FLOAT,
96         VARIABLE_TYPE_INT,
97         VARIABLE_TYPE_IVEC2,
98         VARIABLE_TYPE_IVEC3,
99         VARIABLE_TYPE_IVEC4,
100         VARIABLE_TYPE_MAT2,
101         VARIABLE_TYPE_MAT2X3,
102         VARIABLE_TYPE_MAT2X4,
103         VARIABLE_TYPE_MAT3,
104         VARIABLE_TYPE_MAT3X2,
105         VARIABLE_TYPE_MAT3X4,
106         VARIABLE_TYPE_MAT4,
107         VARIABLE_TYPE_MAT4X2,
108         VARIABLE_TYPE_MAT4X3,
109         VARIABLE_TYPE_UINT,
110         VARIABLE_TYPE_UVEC2,
111         VARIABLE_TYPE_UVEC3,
112         VARIABLE_TYPE_UVEC4,
113         VARIABLE_TYPE_VEC2,
114         VARIABLE_TYPE_VEC3,
115         VARIABLE_TYPE_VEC4,
116 
117         /* Always last */
118         VARIABLE_TYPE_UNKNOWN
119     };
120 
121     /* Public static methods */
122     static _variable_type getBaseVariableType(_variable_type type);
123     static unsigned int getBaseVariableTypeComponentSize(_variable_type type);
124     static unsigned char getComponentAtIndex(unsigned int index);
125 
126     static _variable_type getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows);
127 
128     static std::string getFPVariableTypeStringForVariableType(_variable_type type);
129     static glw::GLenum getGLDataTypeOfBaseVariableType(_variable_type type);
130     static glw::GLenum getGLDataTypeOfVariableType(_variable_type type);
131 
132     static _variable_type getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows);
133 
134     static unsigned int getNumberOfColumnsForVariableType(_variable_type type);
135     static unsigned int getNumberOfComponentsForVariableType(_variable_type type);
136     static unsigned int getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type);
137     static unsigned int getNumberOfRowsForVariableType(_variable_type type);
138 
139     static _variable_type getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a,
140                                                                   _variable_type type_matrix_b);
141 
142     static std::string getStringForVariableTypeValue(_variable_type type, const unsigned char *data_ptr);
143 
144     static _variable_type getTransposedMatrixVariableType(_variable_type type);
145 
146     static _variable_type getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows);
147 
148     static std::string getVariableTypeString(_variable_type type);
149 
150     static bool isGLVersionAtLeast(const glw::Functions &gl, glw::GLint required_major, glw::GLint required_minor);
151 
152     static bool isMatrixVariableType(_variable_type type);
153     static bool isScalarVariableType(_variable_type type);
154 
155     static void replaceToken(const glw::GLchar *token, size_t &search_position, const glw::GLchar *text,
156                              std::string &string);
157 };
158 
159 /** Make sure errors as per spec are generated for new entry-points.
160  *
161  * a) Make sure GL_INVALID_OPERATION is generated by glUniform*() and
162  *    glUniformMatrix*() functions if there is no current program object.
163  * b) Make sure GL_INVALID_OPERATION is generated by glUniform*() if
164  *    the size of the uniform variable declared in the shader does not
165  *    match the size indicated by the command.
166  * c) Make sure GL_INVALID_OPERATION is generated if glUniform*() and
167  *    glUniformMatrix*() are used to load a uniform variable of type
168  *    bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4,
169  *    unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array
170  *    of these.
171  * d) Make sure GL_INVALID_OPERATION is generated if glUniform*() and
172  *    glUniformMatrix*() are used to load incompatible double-typed
173  *    uniforms, as presented below:
174  *
175  *    I.    double-typed uniform configured by glUniform2d();
176  *    II.   double-typed uniform configured by glUniform3d();
177  *    III.  double-typed uniform configured by glUniform4d();
178  *    IV.   double-typed uniform configured by glUniformMatrix*();
179  *    V.    dvec2-typed  uniform configured by glUniform1d();
180  *    VI.   dvec2-typed  uniform configured by glUniform3d();
181  *    VII.  dvec2-typed  uniform configured by glUniform4d();
182  *    VIII. dvec2-typed  uniform configured by glUniformMatrix*();
183  *
184  *                             (etc.)
185  *
186  * e) Make sure GL_INVALID_OPERATION is generated if <location> of
187  *    glUniform*() and glUniformMatrix*() is an invalid uniform
188  *    location for the current program object and location is not
189  *    equal to -1.
190  * f) Make sure GL_INVALID_VALUE is generated if <count> of
191  *    glUniform*() (*dv() functions only) and glUniformMatrix*() is
192  *    negative.
193  * g) Make sure GL_INVALID_OPERATION is generated if <count> of
194  *    glUniform*() (*dv() functions only) and glUniformMatrix*() is
195  *    greater than 1 and the indicated uniform variable is not an
196  *    array variable.
197  * h) Make sure GL_INVALID_OPERATION is generated if a sampler is
198  *    loaded by glUniform*() and glUniformMatrix*().
199  * i) Make sure GL_INVALID_OPERATION is generated if glUniform*() and
200  *    glUniformMatrix*() is used to load values for uniforms of
201  *    boolean types.
202  */
203 class GPUShaderFP64Test1 : public deqp::TestCase
204 {
205 public:
206     /* Public methods */
207     GPUShaderFP64Test1(deqp::Context &context);
208 
209     void deinit();
210     virtual tcu::TestNode::IterateResult iterate();
211 
212     /* Private type definitions */
213 private:
214     typedef enum
215     {
216         UNIFORM_FUNCTION_FIRST,
217 
218         UNIFORM_FUNCTION_1D = UNIFORM_FUNCTION_FIRST,
219         UNIFORM_FUNCTION_1DV,
220         UNIFORM_FUNCTION_2D,
221         UNIFORM_FUNCTION_2DV,
222         UNIFORM_FUNCTION_3D,
223         UNIFORM_FUNCTION_3DV,
224         UNIFORM_FUNCTION_4D,
225         UNIFORM_FUNCTION_4DV,
226 
227         UNIFORM_FUNCTION_MATRIX2DV,
228         UNIFORM_FUNCTION_MATRIX2X3DV,
229         UNIFORM_FUNCTION_MATRIX2X4DV,
230         UNIFORM_FUNCTION_MATRIX3DV,
231         UNIFORM_FUNCTION_MATRIX3X2DV,
232         UNIFORM_FUNCTION_MATRIX3X4DV,
233         UNIFORM_FUNCTION_MATRIX4DV,
234         UNIFORM_FUNCTION_MATRIX4X2DV,
235         UNIFORM_FUNCTION_MATRIX4X3DV,
236 
237         /* Always last */
238         UNIFORM_FUNCTION_COUNT
239     } _uniform_function;
240 
241     /* Private methods */
242     const char *getUniformFunctionString(_uniform_function func);
243     const char *getUniformNameForLocation(glw::GLint location);
244     void initTest();
245     bool isMatrixUniform(glw::GLint uniform_location);
246     bool isMatrixUniformFunction(_uniform_function func);
247     bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans();
248     bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers();
249     bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount();
250     bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation();
251     bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount();
252     bool verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions();
253     bool verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions();
254     bool verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions();
255     bool verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO();
256 
257     /* Private fields */
258     bool m_has_test_passed;
259     glw::GLint m_po_bool_arr_uniform_location;
260     glw::GLint m_po_bool_uniform_location;
261     glw::GLint m_po_bvec2_arr_uniform_location;
262     glw::GLint m_po_bvec2_uniform_location;
263     glw::GLint m_po_bvec3_arr_uniform_location;
264     glw::GLint m_po_bvec3_uniform_location;
265     glw::GLint m_po_bvec4_arr_uniform_location;
266     glw::GLint m_po_bvec4_uniform_location;
267     glw::GLint m_po_dmat2_arr_uniform_location;
268     glw::GLint m_po_dmat2_uniform_location;
269     glw::GLint m_po_dmat2x3_arr_uniform_location;
270     glw::GLint m_po_dmat2x3_uniform_location;
271     glw::GLint m_po_dmat2x4_arr_uniform_location;
272     glw::GLint m_po_dmat2x4_uniform_location;
273     glw::GLint m_po_dmat3_arr_uniform_location;
274     glw::GLint m_po_dmat3_uniform_location;
275     glw::GLint m_po_dmat3x2_arr_uniform_location;
276     glw::GLint m_po_dmat3x2_uniform_location;
277     glw::GLint m_po_dmat3x4_arr_uniform_location;
278     glw::GLint m_po_dmat3x4_uniform_location;
279     glw::GLint m_po_dmat4_arr_uniform_location;
280     glw::GLint m_po_dmat4_uniform_location;
281     glw::GLint m_po_dmat4x2_arr_uniform_location;
282     glw::GLint m_po_dmat4x2_uniform_location;
283     glw::GLint m_po_dmat4x3_arr_uniform_location;
284     glw::GLint m_po_dmat4x3_uniform_location;
285     glw::GLint m_po_double_arr_uniform_location;
286     glw::GLint m_po_double_uniform_location;
287     glw::GLint m_po_dvec2_arr_uniform_location;
288     glw::GLint m_po_dvec2_uniform_location;
289     glw::GLint m_po_dvec3_arr_uniform_location;
290     glw::GLint m_po_dvec3_uniform_location;
291     glw::GLint m_po_dvec4_arr_uniform_location;
292     glw::GLint m_po_dvec4_uniform_location;
293     glw::GLint m_po_float_arr_uniform_location;
294     glw::GLint m_po_float_uniform_location;
295     glw::GLint m_po_int_arr_uniform_location;
296     glw::GLint m_po_int_uniform_location;
297     glw::GLint m_po_ivec2_arr_uniform_location;
298     glw::GLint m_po_ivec2_uniform_location;
299     glw::GLint m_po_ivec3_arr_uniform_location;
300     glw::GLint m_po_ivec3_uniform_location;
301     glw::GLint m_po_ivec4_arr_uniform_location;
302     glw::GLint m_po_ivec4_uniform_location;
303     glw::GLint m_po_sampler_uniform_location;
304     glw::GLint m_po_uint_arr_uniform_location;
305     glw::GLint m_po_uint_uniform_location;
306     glw::GLint m_po_uvec2_arr_uniform_location;
307     glw::GLint m_po_uvec2_uniform_location;
308     glw::GLint m_po_uvec3_arr_uniform_location;
309     glw::GLint m_po_uvec3_uniform_location;
310     glw::GLint m_po_uvec4_arr_uniform_location;
311     glw::GLint m_po_uvec4_uniform_location;
312     glw::GLint m_po_vec2_arr_uniform_location;
313     glw::GLint m_po_vec2_uniform_location;
314     glw::GLint m_po_vec3_arr_uniform_location;
315     glw::GLint m_po_vec3_uniform_location;
316     glw::GLint m_po_vec4_arr_uniform_location;
317     glw::GLint m_po_vec4_uniform_location;
318     glw::GLuint m_po_id;
319     glw::GLuint m_vs_id;
320 };
321 
322 /** Implements "Subtest 2" from CTS_ARB_gpu_shader_fp64, description follows:
323  *  Make sure that it is possible to use:
324  *
325  *  a) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 2) double uniforms
326  *    in a default uniform block of a vertex shader;
327  *  b) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4) dvec2 uniforms
328  *    in a default uniform block of a vertex shader;
329  *  c) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 6) dvec3 uniforms
330  *    in a default uniform block of a vertex shader;
331  *  d) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 8) dvec4 uniforms
332  *    in a default uniform block of a vertex shader;
333  *  e) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 16) dmat2, dmat2x3,
334  *    dmat2x4, dmat3x2, dmat4x2 uniforms in a default uniform block
335  *    of a vertex shader; (each type tested in a separate shader)
336  *  f) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 24) dmat3, dmat3x4,
337  *    dmat4x3 uniforms in a default uniform block of a vertex shader;
338  *    (each type tested in a separate shader)
339  *  g) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 32) dmat4 uniforms
340  *    in a default uniform block of a vertex shader;
341  *  h) arrayed cases of a)-g), where the array size is 3 and the
342  *    amount of uniforms that can be supported should be divided
343  *    by three as well.
344  *  i) cases a)-h), where "vertex shader" is replaced by "fragment
345  *    shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to
346  *    GL_MAX_FRAGMENT_UNIFORM_COMPONENTS;
347  *  j) cases a)-h) where "vertex shader" is replaced by "geometry
348  *    shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to
349  *    GL_MAX_GEOMETRY_UNIFORM_COMPONENTS;
350  *  k) cases a)-h) where "vertex shader" is replaced by "compute
351  *    shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to
352  *    GL_MAX_COMPUTE_UNIFORM_COMPONENTS;
353  *  l) cases a)-h) where "vertex shader" is replaced by "tessellation
354  *    control shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed
355  *    to GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS;
356  *  m) cases a)-h) where "vertex shader" is replaced by "tessellation
357  *    evaluation shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is
358  *    changed to GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS;
359  *
360  *  For each case considered, the test should only define uniforms
361  *  for the stage the test is dealing with.
362  *
363  *  All uniform components considered as a whole should be assigned
364  *  unique values, where the very first uniform component is set to
365  *  a value of 1, the one following set to 2, the one afterward set
366  *  to 3, and so on.
367  *
368  *  For "vertex shader" cases, the test should work by creating
369  *  a program object, to which a vertex shader (as per test case)
370  *  would be attached. The shader would then read all the uniforms,
371  *  verify their values are correct and then set an output bool
372  *  variable to true if the validation passed, false otherwise.
373  *  The test should draw 1024 points, XFB the contents of the output
374  *  variable and verify the result.
375  *
376  *  For "geometry shader" cases, the test should create a program object
377  *  and attach vertex and geometry shaders to it. The vertex shader
378  *  should set gl_Position to (1, 0, 0, 1). The geometry shader
379  *  should accept points on input and emit 1 point, read all the
380  *  uniforms, verify their values are correct and then set an output
381  *  bool variable to true if the validation passed, false otherwise.
382  *  The test should draw 1024 points, XFB the contents of the output
383  *  variable and verify the result.
384  *
385  *  For "tessellation control shader" cases, the test should create
386  *  a program object and attach vertex and tessellation control shaders
387  *  to the program object. The vertex shader should set gl_Position
388  *  to (1, 0, 0, 1). The tessellation control shader should output
389  *  a single vertex per patch and set all inner/outer tessellation.
390  *  levels to 1. The shader should read all the uniforms, verify
391  *  their values are correct and then set an output per-vertex bool
392  *  variable to true if the validation passed, false otherwise. The
393  *  test should draw 1024 patches, XFB the contents of the output
394  *  variable and verify the result.
395  *
396  *  For "tessellation evaluation shader" cases, the test should create
397  *  a program object and attach vertex, tessellation control and
398  *  tessellation evaluation shaders to the program object. The vertex
399  *  shader should set gl_Position to (1, 0, 0, 1). The tessellation
400  *  control shader should behave as in "tessellation control shader"
401  *  case. The tessellation evaluation shader should accept isolines
402  *  and work in point mode. The shader should read all the uniforms,
403  *  verify their values are correct and then set an output
404  *  bool variable to true if the validation passed, false otherwise.
405  *  The test should draw 1024 patches, XFB the contents of the output
406  *  variable and verify the result.
407  *
408  *  For "fragment shader" cases, the test should create a program object
409  *  and attach vertex and fragment shaders to the program object. The
410  *  vertex shader should set gl_Position to 4 different values
411  *  (depending on gl_VertexID value), defining screen-space corners
412  *  for a GL_TRIANGLE_FAN-based draw call. The fragment shader should
413  *  read all the uniforms, verify their values are correct and then
414  *  set the output color to vec4(1) if the validation passed, vec4(0)
415  *  otherwise. The test should draw 4 vertices making up a triangle fan,
416  *  read the rasterized image and confirm the result.
417  *
418  *  For all cases apart from "fragment shader", the test should also
419  *  verify that glGetTransformFeedbackVarying() reports correct
420  *  properties for the uniforms.
421  *
422  *  The test should also verify that in all cases glGetActiveUniform()
423  *  reports correct properties for all the defined uniforms.
424  **/
425 class GPUShaderFP64Test2 : public deqp::TestCase
426 {
427 public:
428     /* Public methods */
429     GPUShaderFP64Test2(deqp::Context &context);
430 
431     virtual void deinit();
432     virtual tcu::TestNode::IterateResult iterate();
433 
434 private:
435     /* Private types */
436     typedef glw::GLint captured_varying_type;
437     typedef void(GLW_APIENTRY *arbDispatchComputeFunc)(glw::GLuint num_groups_x, glw::GLuint num_groups_y,
438                                                        glw::GLuint num_groups_z);
439 
440     /** Shader stage enumeration
441      *
442      */
443     enum shaderStage
444     {
445         COMPUTE_SHADER,
446         FRAGMENT_SHADER,
447         GEOMETRY_SHADER,
448         TESS_CTRL_SHADER,
449         TESS_EVAL_SHADER,
450         VERTEX_SHADER,
451     };
452 
453     /** Store details about uniform type
454      *
455      **/
456     struct uniformTypeDetails
457     {
458         uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows);
459 
460         glw::GLuint m_n_columns;
461         glw::GLuint m_n_rows;
462         glw::GLenum m_type;
463         std::string m_type_name;
464     };
465 
466     /** Store details about uniform
467      *
468      **/
469     struct uniformDetails
470     {
471         glw::GLuint m_array_stride;
472         glw::GLuint m_matrix_stride;
473         glw::GLuint m_offset;
474     };
475 
476     /* Provate methods */
477     glw::GLenum getCapturedPrimitiveType(shaderStage shader_stage) const;
478     glw::GLenum getDrawPrimitiveType(shaderStage shader_stage) const;
479     glw::GLuint getMaxUniformComponents(shaderStage shader_stage) const;
480     glw::GLuint getMaxUniformBlockSize() const;
481     glw::GLuint getRequiredComponentsNumber(const uniformTypeDetails &uniform_type) const;
482     glw::GLuint getUniformTypeMemberSize(const uniformTypeDetails &uniform_type) const;
483     glw::GLuint getAmountUniforms(shaderStage shader_stage, const uniformTypeDetails &uniform_type) const;
484     const glw::GLchar *getShaderStageName(shaderStage shader_stage) const;
485 
486     void inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms, const uniformTypeDetails &uniform_type,
487                         glw::GLint &out_buffer_size, uniformDetails &out_offsets,
488                         glw::GLuint &uniform_block_index) const;
489 
490     void prepareBoilerplateShader(const glw::GLchar *stage_specific_layout, const glw::GLchar *stage_specific_main_body,
491                                   std::string &out_source_code) const;
492 
493     void prepareProgram(shaderStage shader_stage, const uniformTypeDetails &uniform_type,
494                         Utils::programInfo &out_program_info) const;
495 
496     void prepareShaderStages();
497 
498     void prepareTestShader(const glw::GLchar *stage_specific_layout, const glw::GLchar *uniform_definitions,
499                            const glw::GLchar *in_variable_definitions, const glw::GLchar *out_variable_definitions,
500                            const glw::GLchar *uniform_verification, const glw::GLchar *stage_specific_main_body,
501                            std::string &out_source_code) const;
502 
503     void prepareTestComputeShader(const glw::GLchar *uniform_definitions, const glw::GLchar *uniform_verification,
504                                   std::string &out_source_code) const;
505 
506     void prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails &uniform_type,
507                                    std::string &out_source_code) const;
508 
509     void prepareUniforms(shaderStage shader_stage, const uniformTypeDetails &uniform_type,
510                          const Utils::programInfo &program_info) const;
511 
512     void prepareUniformTypes();
513 
514     void prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails &uniform_type,
515                                     std::string &out_source_code) const;
516 
517     bool test(shaderStage shader_stage, const uniformTypeDetails &uniform_type) const;
518 
519     void testBegin(glw::GLuint program_id, shaderStage shader_stage) const;
520 
521     void testEnd(shaderStage shader_stage) const;
522     void testInit();
523     bool verifyResults(shaderStage shader_stage) const;
524 
525     /* Private constants */
526     static const glw::GLuint m_n_captured_results;
527     static const glw::GLint m_result_failure;
528     static const glw::GLint m_result_success;
529     static const glw::GLuint m_texture_width;
530     static const glw::GLuint m_texture_height;
531     static const glw::GLuint m_transform_feedback_buffer_size;
532 
533     static const glw::GLchar *m_uniform_block_name;
534 
535     static const glw::GLenum ARB_MAX_COMPUTE_UNIFORM_COMPONENTS;
536 
537     /* Private fields */
538     arbDispatchComputeFunc m_pDispatchCompute;
539 
540     std::vector<shaderStage> m_shader_stages;
541     std::vector<uniformTypeDetails> m_uniform_types;
542 
543     glw::GLuint m_framebuffer_id;
544     glw::GLuint m_texture_id;
545     glw::GLuint m_transform_feedback_buffer_id;
546     glw::GLuint m_uniform_buffer_id;
547     glw::GLuint m_vertex_array_object_id;
548 };
549 
550 /** Implements "Subtest 3" from CTS_ARB_gpu_shader_fp64, description follows:
551  *
552  *  Make sure it is possible to use new types for member declaration
553  *  in a named uniform block.
554  *  The following members should be defined in the block:
555  *
556  *  ivec3   unused1[3];
557  *  double  double_value;
558  *  bool    unused2;
559  *  dvec2   dvec2_value;
560  *  bvec3   unused3;
561  *  dvec3   dvec3_value;
562  *  int     unused4[3];
563  *  dvec4   dvec4_value;
564  *  bool    unused5;
565  *  bool    unused6[2];
566  *  dmat2   dmat2_value;
567  *  dmat3   dmat3_value;
568  *  bool    unused7;
569  *  dmat4   dmat4_value;
570  *  dmat2x3 dmat2x3_value;
571  *  uvec3   unused8;
572  *  dmat2x4 dmat2x4_value;
573  *  dmat3x2 dmat3x2_value;
574  *  bool    unused9;
575  *  dmat3x4 dmat3x4_value;
576  *  int     unused10;
577  *  dmat4x2 dmat4x2_value;
578  *  dmat4x3 dmat4x3_value;
579  *
580  *  std140, packed and shared layout qualifiers should be tested
581  *  separately.
582  *
583  *  For the purpose of the test, a buffer object, storage of which
584  *  is to be used for the uniform buffer, should be filled with
585  *  predefined values at member-specific offsets. These values
586  *  should then be read in each shader stage covered by the test
587  *  and verified.
588  *
589  *  For std140 layout qualifier, the test should additionally verify
590  *  the offsets assigned by GL implementation are as per specification.
591  *
592  *  The following shader stages should be defined for a program object
593  *  to be used by the test:
594  *
595  *  1) Vertex shader stage;
596  *  2) Geometry shader stage;
597  *  3) Tessellation control shader stage;
598  *  4) Tessellation evaluation shader stage;
599  *  5) Fragment shader stage;
600  *
601  *  Vertex shader stage should set a stage-specific bool variable to
602  *  true if all uniform buffer members are assigned valid values,
603  *  false otherwise.
604  *
605  *  Geometry shader stage should take points on input and emit a single
606  *  point. Similarly to vertex shader stage, it should set a stage-specific
607  *  bool variable to true, if all uniform buffer members are determined
608  *  to expose valid values, false otherwise.
609  *  Geometry shader stage should pass the result value from the vertex
610  *  shader stage down the rendering pipeline using a new output variable,
611  *  set to the value of the variable exposed by vertex shader stage.
612  *
613  *  Tessellation control shader stage should set all inner/outer
614  *  tessellation levels to 1 and output 1 vertex per patch.
615  *  The verification should be carried out as in previous stages.
616  *  TC shader stage should also define stage-specific output variables
617  *  for vertex and geometry shader stages and set them to relevant
618  *  values, similar to what's been described for geometry shader stage.
619  *
620  *  Tessellation evaluation shader stage should take quads on
621  *  input. It should be constructed in a way that will make it
622  *  generate a quad that occupies whole screen-space. This is necessary
623  *  to perform validation of the input variables in fragment shader
624  *  stage.
625  *  The verification should be carried out as in previous stages.
626  *  TE stage should pass down validation results from previous stages
627  *  in a similar manner as was described for TC shader stage.
628  *
629  *  Fragment shader stage should verify all the uniform buffer members
630  *  carry valid values. Upon success, it should output vec4(1) to the
631  *  only output variable. Otherwise, it should set it to vec4(0).
632  *
633  *  XFB should be used to read all the output variables defined in TE
634  *  stage that carry result information from all the rendering stages
635  *  until tessellation evaluation shader stage. The test passes, if
636  *  all result values are set to true and the draw buffer is filled
637  *  with vec4(1).
638  **/
639 class GPUShaderFP64Test3 : public deqp::TestCase
640 {
641 public:
642     /* Public methods */
643     GPUShaderFP64Test3(deqp::Context &);
~GPUShaderFP64Test3()644     virtual ~GPUShaderFP64Test3()
645     {
646     }
647 
648     /* Public methods inherited from TestCase */
649     virtual void deinit(void);
650     virtual tcu::TestNode::IterateResult iterate(void);
651 
652 private:
653     /* Private types */
654 
655     /** Enumerate shader stages
656      *
657      **/
658     enum shaderStage
659     {
660         FRAGMENT_SHADER,
661         GEOMETRY_SHADER,
662         TESS_CONTROL_SHADER,
663         TESS_EVAL_SHADER,
664         VERTEX_SHADER,
665     };
666 
667     /** Enumerate buffer data layouts
668      *
669      **/
670     enum uniformDataLayout
671     {
672         PACKED,
673         SHARED,
674         STD140,
675     };
676 
677     /** Store details about "double precision" uniforms
678      *
679      **/
680     struct uniformDetails
681     {
uniformDetailsgl4cts::GPUShaderFP64Test3::uniformDetails682         uniformDetails(glw::GLint expected_std140_offset, const glw::GLchar *name, glw::GLuint n_columns,
683                        glw::GLuint n_elements, const glw::GLchar *type_name)
684             : m_expected_std140_offset(expected_std140_offset)
685             , m_name(name)
686             , m_n_columns(n_columns)
687             , m_n_elements(n_elements)
688             , m_type_name(type_name)
689         {
690             /* Nothing to be done */
691         }
692 
693         glw::GLint m_expected_std140_offset;
694         const glw::GLchar *m_name;
695         glw::GLuint m_n_columns;
696         glw::GLuint m_n_elements;
697         const glw::GLchar *m_type_name;
698     };
699 
700     /** Store details about program object
701      *
702      **/
703     struct programInfo
704     {
705 
706         programInfo();
707 
708         void compile(deqp::Context &context, glw::GLuint shader_id, const glw::GLchar *shader_code) const;
709 
710         void deinit(deqp::Context &context);
711 
712         void init(deqp::Context &context, const std::vector<uniformDetails> m_uniform_details,
713                   const glw::GLchar *fragment_shader_code, const glw::GLchar *geometry_shader_code,
714                   const glw::GLchar *tesselation_control_shader_code,
715                   const glw::GLchar *tesselation_evaluation_shader_code, const glw::GLchar *vertex_shader_code);
716 
717         void link(deqp::Context &context) const;
718 
719         static const glw::GLint m_invalid_uniform_offset;
720         static const glw::GLint m_invalid_uniform_matrix_stride;
721         static const glw::GLint m_non_matrix_uniform_matrix_stride;
722 
723         glw::GLuint m_fragment_shader_id;
724         glw::GLuint m_geometry_shader_id;
725         glw::GLuint m_program_object_id;
726         glw::GLuint m_tesselation_control_shader_id;
727         glw::GLuint m_tesselation_evaluation_shader_id;
728         glw::GLuint m_vertex_shader_id;
729 
730         glw::GLint m_buffer_size;
731         glw::GLuint m_uniform_block_index;
732 
733         std::vector<glw::GLint> m_uniform_offsets;
734         std::vector<glw::GLint> m_uniform_matrix_strides;
735     };
736 
737     /* Private methods */
738     glw::GLdouble getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const;
739     const programInfo &getProgramInfo(uniformDataLayout uniform_data_layout) const;
740     const glw::GLchar *getUniformLayoutName(uniformDataLayout uniform_data_layout) const;
741 
742     void prepareProgram(programInfo &program_info, uniformDataLayout uniform_data_layout) const;
743 
744     bool prepareUniformBuffer(const programInfo &program_info, bool verify_offsets) const;
745 
746     void testInit();
747     bool test(uniformDataLayout uniform_data_layout) const;
748     bool verifyResults() const;
749 
750     void writeMainBody(std::ostream &stream, shaderStage shader_stage) const;
751 
752     void writePreamble(std::ostream &stream, shaderStage shader_stage) const;
753 
754     void writeUniformBlock(std::ostream &stream, uniformDataLayout uniform_data_layout) const;
755 
756     void writeVaryingDeclarations(std::ostream &stream, shaderStage shader_stage) const;
757 
758     void writeVaryingPassthrough(std::ostream &stream, shaderStage shader_stage) const;
759 
760     /* Private fields */
761     /* Constants */
762     static const glw::GLuint m_result_failure;
763     static const glw::GLuint m_result_success;
764 
765     static const glw::GLchar *m_uniform_block_name;
766     static const glw::GLchar *m_uniform_block_instance_name;
767 
768     static const glw::GLchar *m_varying_name_fs_out_fs_result;
769     static const glw::GLchar *m_varying_name_gs_fs_gs_result;
770     static const glw::GLchar *m_varying_name_gs_fs_tcs_result;
771     static const glw::GLchar *m_varying_name_gs_fs_tes_result;
772     static const glw::GLchar *m_varying_name_gs_fs_vs_result;
773     static const glw::GLchar *m_varying_name_tcs_tes_tcs_result;
774     static const glw::GLchar *m_varying_name_tcs_tes_vs_result;
775     static const glw::GLchar *m_varying_name_tes_gs_tcs_result;
776     static const glw::GLchar *m_varying_name_tes_gs_tes_result;
777     static const glw::GLchar *m_varying_name_tes_gs_vs_result;
778     static const glw::GLchar *m_varying_name_vs_tcs_vs_result;
779 
780     /* GL objects */
781     glw::GLuint m_color_texture_id;
782     glw::GLuint m_framebuffer_id;
783     glw::GLuint m_transform_feedback_buffer_id;
784     glw::GLuint m_uniform_buffer_id;
785     glw::GLuint m_vertex_array_object_id;
786 
787     /* Random values used by getExpectedValue */
788     glw::GLdouble m_base_element;
789     glw::GLdouble m_base_type_ordinal;
790 
791     /* Program details, one per data layout */
792     programInfo m_packed_program;
793     programInfo m_shared_program;
794     programInfo m_std140_program;
795 
796     /* Storage for uniforms' details */
797     std::vector<uniformDetails> m_uniform_details;
798 };
799 
800 /** Make sure glGetUniformdv() reports correct values, as assigned
801  *  by corresponding glUniform*() functions, for the following
802  *  uniform types:
803  *
804  *  a) double;
805  *  b) dvec2;
806  *  c) dvec3;
807  *  d) dvec4;
808  *  e) Arrays of a)-d);
809  *  f) a)-d) defined in single-dimensional arrays built of the same
810  *     structure.
811  *
812  *  These uniforms should be defined in the default uniform block,
813  *  separately in each stage defined for the following program
814  *  objects:
815  *
816  *  a) A program object consisting of a fragment, geometry, tessellation
817  *     control, tessellation evaluation, vertex shader stages.
818  *  b) A program object consisting of a compute shader stage.
819  *
820  *  If GL_ARB_program_interface_query is supported, the test should
821  *  also verify that the following API functions work correctly with
822  *  the described uniforms:
823  *
824  *  - glGetProgramResourceiv()    (query GL_TYPE and GL_ARRAY_SIZE
825  *                                 properties of GL_UNIFORM interface
826  *                                 for all uniforms);
827  *  - glGetProgramResourceIndex() (use GL_UNIFORM interface)
828  *  - glGetProgramResourceName()  (use GL_UNIFORM interface)
829  *
830  *  To verify the values returned by these functions, values returned
831  *  by relevant glGetUniform*() API functions should be used as
832  *  reference.
833  */
834 class GPUShaderFP64Test4 : public deqp::TestCase
835 {
836 public:
837     /* Public methods */
838     GPUShaderFP64Test4(deqp::Context &context);
839 
840     virtual void deinit();
841     virtual tcu::TestNode::IterateResult iterate();
842 
843 private:
844     /* Private type definitions */
845     /* Defines a type used as a data container for one of the test cases */
846     typedef std::pair<glw::GLint /* uniform location */, double * /* value(s) assigned */> uniform_value_pair;
847 
848     /* Holds uniform locations & associated values. used by one of the test cases */
849     struct _data
850     {
851         _data();
852 
853         double uniform_double;
854         double uniform_double_arr[2];
855         double uniform_dvec2[2];
856         double uniform_dvec2_arr[4];
857         double uniform_dvec3[3];
858         double uniform_dvec3_arr[6];
859         double uniform_dvec4[4];
860         double uniform_dvec4_arr[8];
861 
862         glw::GLint uniform_location_double;
863         glw::GLint uniform_location_double_arr[2];
864         glw::GLint uniform_location_dvec2;
865         glw::GLint uniform_location_dvec2_arr[2];
866         glw::GLint uniform_location_dvec3;
867         glw::GLint uniform_location_dvec3_arr[2];
868         glw::GLint uniform_location_dvec4;
869         glw::GLint uniform_location_dvec4_arr[2];
870     };
871 
872     /** Holds uniform location & properties information. Used by one of the test cases. */
873     struct _program_interface_query_test_item
874     {
875         glw::GLint expected_array_size;
876         std::string name;
877         glw::GLenum expected_type;
878         glw::GLint location;
879     };
880 
881     /** Holds information on all uniforms defined for a single shader stage. */
882     struct _stage_data
883     {
884         _data uniform_structure_arrays[2];
885         _data uniforms;
886     };
887 
888     /* Private methods */
889     void generateUniformValues();
890     void initProgramObjects();
891     void initTest();
892     void initUniformValues();
893     bool verifyProgramInterfaceQuerySupport();
894     bool verifyUniformValues();
895 
896     /* Private declarations */
897     bool m_has_test_passed;
898     char *m_uniform_name_buffer;
899 
900     glw::GLuint m_cs_id;
901     glw::GLuint m_fs_id;
902     glw::GLuint m_gs_id;
903     glw::GLuint m_po_cs_id;
904     glw::GLuint m_po_noncs_id;
905     glw::GLuint m_tc_id;
906     glw::GLuint m_te_id;
907     glw::GLuint m_vs_id;
908 
909     _stage_data m_data_cs;
910     _stage_data m_data_fs;
911     _stage_data m_data_gs;
912     _stage_data m_data_tc;
913     _stage_data m_data_te;
914     _stage_data m_data_vs;
915 };
916 
917 /** Make sure the following implicit conversion work correctly:
918  *
919  *   a) int    -> double;
920  *   b) ivec2  -> dvec2;
921  *   c) ivec3  -> dvec3;
922  *   d) ivec4  -> dvec4;
923  *   e) uint   -> double;
924  *   f) uvec2  -> dvec2;
925  *   g) uvec3  -> dvec3;
926  *   h) uvec4  -> dvec4;
927  *   i) float  -> double;
928  *   j) vec2   -> dvec2;
929  *   k) vec3   -> dvec3;
930  *   l) vec4   -> dvec4;
931  *   m) mat2   -> dmat2;
932  *   n) mat3   -> dmat3;
933  *   o) mat4   -> dmat4;
934  *   p) mat2x3 -> dmat2x3;
935  *   q) mat2x4 -> dmat2x4;
936  *   r) mat3x2 -> dmat3x2;
937  *   s) mat3x4 -> dmat3x4;
938  *   t) max4x2 -> dmat4x2;
939  *   u) mat4x3 -> dmat4x3;
940  *
941  *   The test should also verify the following explicit conversions
942  *   are supported (that is: when the right-side value is used as
943  *   an argument to a constructor of left-side type):
944  *
945  *   a) int    -> double;
946  *   b) uint   -> double;
947  *   c) float  -> double;
948  *   d) double -> int;
949  *   e) double -> uint;
950  *   f) double -> float;
951  *   g) double -> bool;
952  *   h) bool   -> double;
953  *
954  *   For each conversion, the test should create a program object and
955  *   attach a vertex shader to it.
956  *   The shader should define an uniform named "base_value", with
957  *   its type dependent on the type defined left-side for particular
958  *   case, as defined below:
959  *
960  *   [base_value type: bool]
961  *   bool
962  *
963  *   [base_value type: double]
964  *   double
965  *
966  *   [base_value type: int]
967  *   int, ivec2, ivec3, ivec4
968  *
969  *   [base_value type: uint]
970  *   uint, uvec2, uvec3, uvec4
971  *
972  *   [base_value type: float]
973  *   float,  vec2,   vec3,   vec4,
974  *   mat2,   mat3,   mat4,   mat2x3,
975  *   mat2x4, mat3x2, mat3x4, mat4x2,
976  *   mat4x3
977  *
978  *   For each tested pair, it should build the "source" value/vector/matrix
979  *   by taking the value specified in uniform of the same type as the one
980  *   that is to be used as source, and use it for zeroth component. First
981  *   component should be larger by one, second component should be bigger
982  *   by two, and so on.
983  *   Once the source value/vector/matrix is defined, the casting operation
984  *   should be performed, giving a "destination" value/vector/matrix of
985  *   type as defined for particular case.
986  *   The resulting value should be XFBed out to the test implementation.
987  *   The comparison should be performed on CPU to ensure validity of
988  *   the resulting data.
989  *
990  *   A swizzling operator should be used where possible when setting
991  *   the output variables to additionally check that swizzling works
992  *   correctly for multi-component double-precision types.
993  *
994  *   The program object should be used for the following base values:
995  *
996  *   a) -25.12065
997  *   b)   0.0
998  *   c)   0.001
999  *   d)   1.0
1000  *   e) 256.78901
1001  *
1002  *   An epsilon of 1e-5 should be used for floating-point comparisons.
1003  **/
1004 class GPUShaderFP64Test5 : public deqp::TestCase
1005 {
1006 public:
1007     /* Public methods */
1008     GPUShaderFP64Test5(deqp::Context &context);
1009 
1010     virtual void deinit();
1011     virtual tcu::TestNode::IterateResult iterate();
1012 
1013 private:
1014     /* Private type definitions */
1015     /* Defines swizzle operators used by shaders generated by the test */
1016     enum _swizzle_type
1017     {
1018         SWIZZLE_TYPE_NONE,
1019 
1020         SWIZZLE_TYPE_XWZY,
1021         SWIZZLE_TYPE_XZXY,
1022         SWIZZLE_TYPE_XZY,
1023         SWIZZLE_TYPE_XZYW,
1024 
1025         SWIZZLE_TYPE_Y,
1026         SWIZZLE_TYPE_YX,
1027         SWIZZLE_TYPE_YXX,
1028         SWIZZLE_TYPE_YXXY,
1029 
1030         SWIZZLE_TYPE_Z,
1031         SWIZZLE_TYPE_ZY,
1032 
1033         SWIZZLE_TYPE_W,
1034         SWIZZLE_TYPE_WX,
1035     };
1036 
1037     /* Defines cast type to be used for specific test case */
1038     enum _test_case_type
1039     {
1040         TEST_CASE_TYPE_EXPLICIT,
1041         TEST_CASE_TYPE_IMPLICIT,
1042 
1043         /* Always last */
1044         TEST_CASE_TYPE_UNKNOWN
1045     };
1046 
1047     /* Holds a complete description of a single test case */
1048     struct _test_case
1049     {
1050         _test_case_type type;
1051 
1052         Utils::_variable_type src_type;
1053         Utils::_variable_type dst_type;
1054 
1055         std::string shader_body;
1056     };
1057 
1058     /* Private methods */
1059     bool executeIteration(const _test_case &test_case);
1060 
1061     void getSwizzleTypeProperties(_swizzle_type type, std::string *out_swizzle_string, unsigned int *out_n_components,
1062                                   unsigned int *out_component_order);
1063 
1064     std::string getVertexShaderBody(const _test_case &test_case);
1065     void initIteration(_test_case &test_case);
1066     void initTest();
1067 
1068     bool verifyXFBData(const unsigned char *data_ptr, const _test_case &test_case);
1069 
1070     void deinitInteration();
1071 
1072     /* Private declarations */
1073     unsigned char *m_base_value_bo_data;
1074     glw::GLuint m_base_value_bo_id;
1075     bool m_has_test_passed;
1076     glw::GLint m_po_base_value_attribute_location;
1077     glw::GLint m_po_id;
1078     glw::GLuint m_vao_id;
1079     glw::GLint m_vs_id;
1080     glw::GLuint m_xfb_bo_id;
1081     unsigned int m_xfb_bo_size;
1082 
1083     float m_base_values[5]; /* as per test spec */
1084     _swizzle_type m_swizzle_matrix[4 /* max number of dst components */][4 /* max number of src components */];
1085 };
1086 
1087 /** The test should verify it is a compilation error to perform the
1088  * following casts in the shader:
1089  *
1090  * a) int   [2] -> double;
1091  * b) ivec2 [2] -> dvec2;
1092  * c) ivec3 [2] -> dvec3;
1093  * d) ivec4 [2] -> dvec4;
1094  * e) uint  [2] -> double;
1095  * f) uvec2 [2] -> dvec2;
1096  * g) uvec3 [2] -> dvec3;
1097  * h) uvec4 [2] -> dvec4;
1098  * i) float [2] -> double;
1099  * j) vec2  [2] -> dvec2;
1100  * k) vec3  [2] -> dvec3;
1101  * l) vec4  [2] -> dvec4;
1102  * m) mat2  [2] -> dmat2;
1103  * n) mat3  [2] -> dmat3;
1104  * o) mat4  [2] -> dmat4;
1105  * p) mat2x3[2] -> dmat2x3;
1106  * q) mat2x4[2] -> dmat2x4;
1107  * r) mat3x2[2] -> dmat3x2;
1108  * s) mat3x4[2] -> dmat3x4;
1109  * t) mat4x2[2] -> dmat4x2;
1110  * u) mat4x3[2] -> dmat4x3;
1111  *
1112  * The test should also attempt to cast all types defined left-side
1113  * in a)-u) to structures, where the only variable embedded inside
1114  * the structure would be defined on the right-side of the test
1115  * case considered.
1116  *
1117  * The following shader stages should be considered for the purpose
1118  * of the test:
1119  *
1120  * 1) Fragment shader stage;
1121  * 2) Geometry shader stage;
1122  * 3) Tessellation control shader stage;
1123  * 4) Tessellation evaluation shader stage;
1124  * 5) Vertex shader stage;
1125  * 6) Compute shader stage;
1126  **/
1127 class GPUShaderFP64Test6 : public deqp::TestCase
1128 {
1129 public:
1130     /* Public methods */
1131     GPUShaderFP64Test6(deqp::Context &context);
1132 
1133     virtual void deinit();
1134     virtual tcu::TestNode::IterateResult iterate();
1135 
1136 private:
1137     /* Private type definitions */
1138 
1139     /* Holds a complete description of a single test case */
1140     struct _test_case
1141     {
1142         unsigned int src_array_size;
1143         Utils::_variable_type src_type;
1144         Utils::_variable_type dst_type;
1145 
1146         bool wrap_dst_type_in_structure;
1147 
1148         std::string cs_shader_body;
1149         std::string fs_shader_body;
1150         std::string gs_shader_body;
1151         std::string tc_shader_body;
1152         std::string te_shader_body;
1153         std::string vs_shader_body;
1154     };
1155 
1156     /* Private methods */
1157     bool executeIteration(const _test_case &test_case);
1158     std::string getComputeShaderBody(const _test_case &test_case);
1159     std::string getFragmentShaderBody(const _test_case &test_case);
1160     std::string getGeometryShaderBody(const _test_case &test_case);
1161     std::string getTessellationControlShaderBody(const _test_case &test_case);
1162     std::string getTessellationEvaluationShaderBody(const _test_case &test_case);
1163     std::string getVertexShaderBody(const _test_case &test_case);
1164 
1165     void initTest();
1166     void initIteration(_test_case &test_case);
1167 
1168     /* Private declarations */
1169     glw::GLuint m_cs_id;
1170     glw::GLuint m_fs_id;
1171     glw::GLuint m_gs_id;
1172     glw::GLuint m_tc_id;
1173     glw::GLuint m_te_id;
1174     glw::GLuint m_vs_id;
1175 
1176     bool m_has_test_passed;
1177 };
1178 
1179 /** Make sure that double-precision types (double, dvec2, dvec3,
1180  *  dvec4, dmat2, dmat3, dmat4, dmat2x3, dmat2x4, dmat3x2, dmat3x4,
1181  *  dmat4x2, dmat4x2) and arrays of those:
1182  *
1183  *  a) can be used as varyings (excl. vertex shader inputs *if*
1184  *     GL_ARB_vertex_attrib_64bit support is *not* reported, and
1185  *     fragment shader outputs; 'flat' layout qualifier should be
1186  *     used for transferring data to fragment shader stage);
1187  *  b) cannot be used as fragment shader output; (compilation error
1188  *     expected).
1189  *  c) cannot be used as fragment shader input if 'flat' layout
1190  *     qualifier is missing)
1191  *
1192  *  For case a), the following shader stages should be defined for
1193  *  a single program object:
1194  *
1195  *  1) Vertex shader stage;
1196  *  2) Geometry shader stage;
1197  *  3) Tessellation control shader stage;
1198  *  4) Tessellation evaluation shader stage;
1199  *  5) Fragment shader stage;
1200  *
1201  *  Vertex shader stage should define a single output variable for
1202  *  each type considered. Each component of these output variables
1203  *  should be set to predefined unique values.
1204  *  Geometry shader stage should take points on input and emit a single
1205  *  point. It should take all input variables from the previous stage,
1206  *  add a predefined value to each component and pass it down the
1207  *  rendering pipeline.
1208  *  Tessellation control shader stage should set all inner/outer
1209  *  tessellation levels to 1 and output 1 vertex per patch.
1210  *  It should take all input variables from the previous stage,
1211  *  add a predefined value to each component and pass it to
1212  *  tessellation evaluation stage by using per-vertex outputs.
1213  *  Tessellation evaluation shader stage should take quads on
1214  *  input. It should also define all relevant input variables, as
1215  *  defined by previous stage, add a predefined value to each
1216  *  component and pass it to geometry shader stage. Finally, it
1217  *  should be constructed in a way that will make it generate
1218  *  a quad that occupies whole screen-space. This is necessary
1219  *  to perform validation of the input variables in fragment shader
1220  *  stage.
1221  *  Fragment shader stage should take all inputs, as defined as
1222  *  outputs in tessellation evaluation shader stage. It should
1223  *  verify all the inputs carry valid values. Upon success, it
1224  *  should output vec4(1) to the only output variable. Otherwise,
1225  *  it should set it to vec4(0).
1226  **/
1227 class GPUShaderFP64Test7 : public deqp::TestCase
1228 {
1229 public:
1230     /* Public methods */
1231     GPUShaderFP64Test7(deqp::Context &context);
1232 
1233     virtual void deinit();
1234     virtual tcu::TestNode::IterateResult iterate();
1235 
1236 private:
1237     /* Private type definitions */
1238     struct _variable
1239     {
1240         glw::GLint attribute_location;
1241         unsigned int array_size;
1242         Utils::_variable_type type;
1243     };
1244 
1245     typedef std::vector<_variable> _variables;
1246     typedef _variables::const_iterator _variables_const_iterator;
1247 
1248     /* Private methods */
1249     bool buildTestProgram(_variables &variables);
1250     bool compileShader(glw::GLint shader_id, const std::string &body);
1251     void configureXFBBuffer(const _variables &variables);
1252     bool executeFunctionalTest(_variables &variables);
1253     void generateXFBVaryingNames(const _variables &variables);
1254 
1255     std::string getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(Utils::_variable_type input_variable_type,
1256                                                                        unsigned int array_size);
1257 
1258     std::string getCodeOfFragmentShaderWithDoublePrecisionOutput(Utils::_variable_type output_variable_type,
1259                                                                  unsigned int array_size);
1260 
1261     std::string getFragmentShaderBody(const _variables &variables);
1262     std::string getGeometryShaderBody(const _variables &variables);
1263     std::string getTessellationControlShaderBody(const _variables &variables);
1264     std::string getTessellationEvaluationShaderBody(const _variables &variables);
1265 
1266     std::string getVariableDeclarations(const char *prefix, const _variables &variables,
1267                                         const char *layout_qualifier = "");
1268 
1269     std::string getVertexShaderBody(const _variables &variables);
1270     void initTest();
1271     void logVariableContents(const _variables &variables);
1272     void releaseXFBVaryingNames();
1273     void setInputAttributeValues(const _variables &variables);
1274 
1275     /* Private declarations */
1276     bool m_are_double_inputs_supported;
1277     std::string m_current_fs_body;
1278     std::string m_current_gs_body;
1279     std::string m_current_tc_body;
1280     std::string m_current_te_body;
1281     std::string m_current_vs_body;
1282     glw::GLuint m_fbo_id;
1283     glw::GLint m_fs_id;
1284     glw::GLint m_gs_id;
1285     bool m_has_test_passed;
1286     glw::GLint m_n_max_components_per_stage;
1287     unsigned int m_n_xfb_varyings;
1288     glw::GLint m_po_id;
1289     glw::GLint m_tc_id;
1290     glw::GLint m_te_id;
1291     glw::GLuint m_to_id;
1292     unsigned char *m_to_data;
1293     unsigned int m_to_height;
1294     unsigned int m_to_width;
1295     glw::GLuint m_xfb_bo_id;
1296     glw::GLchar **m_xfb_varyings;
1297     glw::GLuint m_vao_id;
1298     glw::GLint m_vs_id;
1299 };
1300 
1301 /** Make sure that all constructors valid for double-precision
1302  * vector/matrix types are accepted by the GLSL compiler for
1303  * all six shader stages.
1304  *
1305  * The test passes if all shaders compile successfully.
1306  **/
1307 class GPUShaderFP64Test8 : public deqp::TestCase
1308 {
1309 public:
1310     /* Public methods */
1311     GPUShaderFP64Test8(deqp::Context &context);
1312 
1313     virtual void deinit();
1314     virtual tcu::TestNode::IterateResult iterate();
1315 
1316 private:
1317     /* Private type definitions */
1318     typedef std::vector<Utils::_variable_type> _argument_list;
1319     typedef _argument_list::const_iterator _argument_list_const_iterator;
1320     typedef std::vector<_argument_list> _argument_lists;
1321     typedef _argument_lists::const_iterator _argument_lists_const_iterator;
1322 
1323     /* Holds a complete description of a single test case */
1324     struct _argument_list_tree_node;
1325 
1326     typedef std::vector<_argument_list_tree_node *> _argument_list_tree_nodes;
1327     typedef _argument_list_tree_nodes::const_iterator _argument_list_tree_nodes_const_iterator;
1328     typedef std::queue<_argument_list_tree_node *> _argument_list_tree_node_queue;
1329 
1330     struct _argument_list_tree_node
1331     {
1332         _argument_list_tree_nodes children;
1333         int n_components_used;
1334         _argument_list_tree_node *parent;
1335         Utils::_variable_type type;
1336 
~_argument_list_tree_nodegl4cts::GPUShaderFP64Test8::_argument_list_tree_node1337         ~_argument_list_tree_node()
1338         {
1339             while (children.size() > 0)
1340             {
1341                 _argument_list_tree_node *node_ptr = children.back();
1342 
1343                 children.pop_back();
1344 
1345                 delete node_ptr;
1346                 node_ptr = NULL;
1347             }
1348         }
1349     };
1350 
1351     struct _test_case
1352     {
1353         _argument_list argument_list;
1354         Utils::_variable_type type;
1355 
1356         std::string cs_shader_body;
1357         std::string fs_shader_body;
1358         std::string gs_shader_body;
1359         std::string tc_shader_body;
1360         std::string te_shader_body;
1361         std::string vs_shader_body;
1362     };
1363 
1364     /* Private methods */
1365     bool executeIteration(const _test_case &test_case);
1366     _argument_lists getArgumentListsForVariableType(const Utils::_variable_type &variable_type);
1367     std::string getComputeShaderBody(const _test_case &test_case);
1368     std::string getFragmentShaderBody(const _test_case &test_case);
1369     std::string getGeneralBody(const _test_case &test_case);
1370     std::string getGeometryShaderBody(const _test_case &test_case);
1371     std::string getTessellationControlShaderBody(const _test_case &test_case);
1372     std::string getTessellationEvaluationShaderBody(const _test_case &test_case);
1373     std::string getVertexShaderBody(const _test_case &test_case);
1374 
1375     void initTest();
1376     void initIteration(_test_case &test_case);
1377 
1378     /* Private declarations */
1379     glw::GLuint m_cs_id;
1380     glw::GLuint m_fs_id;
1381     glw::GLuint m_gs_id;
1382     glw::GLuint m_tc_id;
1383     glw::GLuint m_te_id;
1384     glw::GLuint m_vs_id;
1385 
1386     bool m_has_test_passed;
1387 };
1388 
1389 /** Make sure that the following operators work correctly for
1390  *  double-precision floating-point scalars, vectors and matrices:
1391  *
1392  *  a) +  (addition)
1393  *  b) -  (subtraction)
1394  *  c) *  (multiplication)
1395  *  d) /  (division)
1396  *  e) -  (negation)
1397  *  f) -- (pre-decrementation and post-decrementation)
1398  *  g) ++ (pre-incrementation and post-incrementation)
1399  *
1400  *  Furthermore, the following relational operators should also be
1401  *  tested for double-precision floating-point expressions:
1402  *
1403  *  a) <  (less than)
1404  *  b) <= (less than or equal)
1405  *  c) >  (greater than)
1406  *  d) >= (greater than or equal)
1407  *
1408  *  For each double-precision floating-point type, the test should
1409  *  create a program object, to which it should then attach
1410  *  a vertex shader, body of which was adjusted to handle case-specific
1411  *  type. The shader should use all the operators and operations
1412  *  described above. The result value should be XFBed out to the
1413  *  test for verification.
1414  *
1415  *  For relational operators, both cases described below should be
1416  *  tested:
1417  *
1418  *  a) fundamental type of the two operands should match without
1419  *     any implicit type conversion involved in the process;
1420  *  b) fundamental type of the two operands should match after an
1421  *     implicit type conversion (use some of the casts enlisted for
1422  *     test 6).
1423  *
1424  *  The test passes if the returned set of values was correct for
1425  *  all the types considered. Assume epsilon value of 1e-5.
1426  *
1427  **/
1428 class GPUShaderFP64Test9 : public deqp::TestCase
1429 {
1430 public:
1431     /* Public methods */
1432     GPUShaderFP64Test9(deqp::Context &context);
1433 
1434     void deinit();
1435     virtual tcu::TestNode::IterateResult iterate();
1436 
1437 private:
1438     /* Private type definitions */
1439     typedef enum
1440     {
1441         OPERATION_TYPE_ADDITION,
1442         OPERATION_TYPE_DIVISION,
1443         OPERATION_TYPE_MULTIPLICATION,
1444         OPERATION_TYPE_SUBTRACTION,
1445         OPERATION_TYPE_PRE_DECREMENTATION,
1446         OPERATION_TYPE_PRE_INCREMENTATION,
1447         OPERATION_TYPE_POST_DECREMENTATION,
1448         OPERATION_TYPE_POST_INCREMENTATION,
1449 
1450         /* Always last */
1451         OPERATION_TYPE_COUNT
1452     } _operation_type;
1453 
1454     struct _test_case
1455     {
1456         _operation_type operation_type;
1457         Utils::_variable_type result_variable_type;
1458         std::string vs_body;
1459         Utils::_variable_type variable_type;
1460     };
1461 
1462     /* Private methods */
1463     bool executeTestIteration(const _test_case &test_case);
1464 
1465     void getMatrixMultiplicationResult(const Utils::_variable_type &matrix_a_type,
1466                                        const std::vector<double> &matrix_a_data,
1467                                        const Utils::_variable_type &matrix_b_type,
1468                                        const std::vector<double> &matrix_b_data, double *out_result_ptr);
1469 
1470     const char *getOperatorForOperationType(const _operation_type &operation_type);
1471     std::string getOperationTypeString(const _operation_type &operation_type);
1472     std::string getVertexShaderBody(_test_case &test_case);
1473     void initTest();
1474     void initTestIteration(_test_case &test_case);
1475 
1476     bool verifyXFBData(const _test_case &test_case, const unsigned char *xfb_data);
1477 
1478     /* Private fields */
1479     bool m_has_test_passed;
1480     glw::GLuint m_po_id;
1481     glw::GLuint m_xfb_bo_id;
1482     glw::GLuint m_vao_id;
1483     glw::GLuint m_vs_id;
1484 };
1485 
1486 /** Group class for GPU Shader FP64 conformance tests */
1487 class GPUShaderFP64Tests : public deqp::TestCaseGroup
1488 {
1489 public:
1490     /* Public methods */
1491     GPUShaderFP64Tests(deqp::Context &context);
~GPUShaderFP64Tests()1492     virtual ~GPUShaderFP64Tests()
1493     {
1494     }
1495 
1496     virtual void init(void);
1497 
1498 private:
1499     /* Private methods */
1500     GPUShaderFP64Tests(const GPUShaderFP64Tests &);
1501     GPUShaderFP64Tests &operator=(const GPUShaderFP64Tests &);
1502 };
1503 
1504 } // namespace gl4cts
1505 
1506 #endif // _GL4CGPUSHADERFP64TESTS_HPP
1507