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