• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ESEXTCTESSELLATIONSHADERTESSELLATION_HPP
2 #define _ESEXTCTESSELLATIONSHADERTESSELLATION_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 #include "../esextcTestCaseBase.hpp"
27 #include "esextcTessellationShaderUtils.hpp"
28 #include "gluShaderUtil.hpp"
29 #include "tcuDefs.hpp"
30 
31 namespace glcts
32 {
33 /** A DEQP CTS test group that collects all tests that verify tessellation
34  *  functionality for multiple primitive modes at once, as opposed to some
35  *  other tests that are mode-specific.
36  */
37 class TessellationShaderTessellationTests : public glcts::TestCaseGroupBase
38 {
39 public:
40 	/* Public methods */
41 	TessellationShaderTessellationTests(glcts::Context& context, const ExtParameters& extParams);
42 
~TessellationShaderTessellationTests(void)43 	virtual ~TessellationShaderTessellationTests(void)
44 	{
45 	}
46 
47 	void init(void);
48 
49 private:
50 	/* Private methods */
51 	TessellationShaderTessellationTests(const TessellationShaderTessellationTests& other);
52 	TessellationShaderTessellationTests& operator=(const TessellationShaderTessellationTests& other);
53 };
54 
55 /** Implementation of Test Case 24
56  *
57  *  Make sure that patches, for which relevant outer tessellation levels have
58  *  been defined to zero or less, are discarded by the tessellation
59  *  primitive generator. Confirm that such patches never reach tessellation
60  *  evaluation shader program.
61  *  Cover all three tessellation primitive generator modes (triangles, quads,
62  *  isolines).
63  *  Note that an assumption was made here that TE's primitive id counter
64  *  works on output patches that are generated afresh from data fed by TC,
65  *  meaning XFBed TE-stage gl_PrimitiveID should be a sequential set, and
66  *  XFBed TC-stage gl_PrimitiveID should be missing every 4th and 6th patch
67  *  vertices.
68  *  This is backed by http://www.khronos.org/bugzilla/show_bug.cgi?id=754
69  *
70  *  Technical details:
71  *
72  *  0. If (gl_PrimitiveID % 4) == 0, TC should set all relevant outer
73  *     tessellation levels to 0.
74  *  1. If (gl_PrimitiveID % 4) == 2, TC should set all relevant outer
75  *     tessellation level to -1.
76  *  2. If (gl_PrimitiveID % 4) == 1 OR (gl_PrimitiveID % 4) == 3, TC should
77  *     set all relevant outer tessellation levels to 1.
78  *  3. Inner tessellation level should always be set to 1.
79  *  4. TC should also set a per-vertex output variable to gl_PrimitiveID
80  *     value.
81  *  5. TC should also pass gl_PrimitiveID to TE.
82  *  6. TE should store both pieces of data using Transform Feedback for each
83  *     patch vertex processed. Test passes if the data retrieved is valid.
84  *
85  *
86  **/
87 class TessellationShaderTessellationInputPatchDiscard : public TestCaseBase
88 {
89 public:
90 	/* Public methods */
91 	TessellationShaderTessellationInputPatchDiscard(Context& context, const ExtParameters& extParams);
92 
~TessellationShaderTessellationInputPatchDiscard(void)93 	virtual ~TessellationShaderTessellationInputPatchDiscard(void)
94 	{
95 	}
96 
97 	virtual void		  deinit(void);
98 	void				  initTest(void);
99 	virtual IterateResult iterate(void);
100 
101 private:
102 	/* Private type definitions */
103 	/** Defines a single test pass */
104 	typedef struct _run
105 	{
106 		glw::GLuint					 po_id;
107 		_tessellation_primitive_mode primitive_mode;
108 		glw::GLuint					 tc_id;
109 		glw::GLuint					 te_id;
110 
_runglcts::TessellationShaderTessellationInputPatchDiscard::_run111 		_run()
112 		{
113 			po_id		   = 0;
114 			primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
115 			tc_id		   = 0;
116 			te_id		   = 0;
117 		}
118 	} _run;
119 
120 	/** Defines a vector of test passes */
121 	typedef std::vector<_run>	 _runs;
122 	typedef _runs::const_iterator _runs_const_iterator;
123 
124 	/* Private methods */
125 	std::string getTCCode();
126 	std::string getTECode(_tessellation_primitive_mode primitive_mode);
127 
128 	void deinitRun(_run& test);
129 	void initRun(_run& test, _tessellation_primitive_mode primitive_mode);
130 
131 	/* Private variables */
132 	glw::GLuint m_bo_id;
133 	glw::GLuint m_fs_id;
134 	glw::GLuint m_vs_id;
135 	glw::GLuint m_vao_id;
136 
137 	_runs					 m_runs;
138 	TessellationShaderUtils* m_utils_ptr;
139 };
140 
141 /**  Implementation for Test Case 18
142  *
143  *   Make sure that tessellation control shader is fed with correct gl_InvocationID
144  *   values.
145  *   Make sure that tessellation control and tessellation evaluation shaders are
146  *   fed with correct gl_PatchVerticesIn values.
147  *   Make sure that tessellation control and tessellation evaluation shaders are
148  *   fed with correct gl_PrimitiveID values. Make sure restarting a primitive
149  *   topology does not restart primitive counter.
150  *
151  *   Technical details:
152  *
153  *   0. The test to be executed for all three geometry types supported by
154  *      the tessellator. The draw calls used should draw at least a few
155  *      instances of a set of patches generating a few primitives for each type
156  *      considered. Vertex arrayed and indiced draw calls should be tested.
157  *      A few vertices-per-patch configurations should be considered.
158  *
159  *   1. Tessellation control shader to pass gl_InvocationID to tessellation
160  *      evaluation shader for XFB, for later inspection. The values captured
161  *      should run from 0 to the last invocation number for particular draw
162  *      call. Whole range should be covered by exactly one appearance of each index.
163  *
164  *   2. Tessellation control shader should pass gl_PatchVerticesIn value to
165  *      tessellation evaluation shader. The value passed from TC, as well as
166  *      gl_PatchVerticesIn value exposed to TE should be captured for later
167  *      inspection.
168  *
169  *   3. Step 2 should be repeated for gl_PrimitiveID. The test should confirm
170  *      that using a primitive restart index does not reset the counter, when
171  *      indiced draw calls are tested.
172  **/
173 class TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID : public TestCaseBase
174 {
175 public:
176 	/* Public methods */
177 	TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(Context&			   context,
178 																			  const ExtParameters& extParams);
179 
~TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(void)180 	virtual ~TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(void)
181 	{
182 	}
183 
184 	virtual void		  deinit(void);
185 	void				  initTest(void);
186 	virtual IterateResult iterate(void);
187 
188 private:
189 	/* Private type definitions */
190 	/** Defines a single test run */
191 	typedef struct _run
192 	{
193 		glw::GLuint					 bo_indices_id;
194 		unsigned int				 drawcall_count_multiplier;
195 		bool						 drawcall_is_indiced;
196 		glw::GLuint					 drawcall_n_instances;
197 		glw::GLuint					 n_instances;
198 		glw::GLint					 n_patch_vertices;
199 		unsigned int				 n_restart_indices;
200 		unsigned int				 n_result_vertices;
201 		glw::GLuint					 po_id;
202 		_tessellation_primitive_mode primitive_mode;
203 		glw::GLuint					 tc_id;
204 		glw::GLuint					 te_id;
205 
_runglcts::TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID::_run206 		_run()
207 		{
208 			bo_indices_id			  = 0;
209 			drawcall_count_multiplier = 0;
210 			drawcall_is_indiced		  = false;
211 			drawcall_n_instances	  = 0;
212 			n_result_vertices		  = 0;
213 			n_instances				  = 0;
214 			n_patch_vertices		  = 0;
215 			n_restart_indices		  = 0;
216 			po_id					  = 0;
217 			primitive_mode			  = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
218 			tc_id					  = 0;
219 			te_id					  = 0;
220 		}
221 	} _run;
222 
223 	/** Defines a vector of test runs */
224 	typedef std::vector<_run>	 _runs;
225 	typedef _runs::const_iterator _runs_const_iterator;
226 
227 	/* Private methods */
228 	std::string getTCCode(glw::GLuint n_patch_vertices);
229 	std::string getTECode(_tessellation_primitive_mode primitive_mode);
230 
231 	void deinitRun(_run& run);
232 
233 	void initRun(_run& run, _tessellation_primitive_mode primitive_mode, glw::GLint n_patch_vertices, bool is_indiced,
234 				 glw::GLint n_instances, unsigned int drawcall_count_multiplier);
235 
236 	/* Private variables */
237 	glw::GLuint m_bo_id;
238 	glw::GLuint m_fs_id;
239 	glw::GLuint m_vs_id;
240 	glw::GLuint m_vao_id;
241 
242 	_runs					 m_runs;
243 	TessellationShaderUtils* m_utils_ptr;
244 };
245 
246 /** Implementation of Test Case 51
247  *
248  *  Make sure that coordinates of all triangles generated by fixed-function
249  *  tessellation primitive generator meet the barycentric coordinate requirement
250  *                            u + v + w = 1
251  *
252  *  Consider a few inner/outer tessellation level combinations
253  *  for triangle and quad inputs of a tessellation evaluation shader.
254  *
255  *  Epsilon: 1e-5. This is dictated by the language in ES 3.0 specification,
256  *  which seems to be the best pick, given that the tessellator is
257  *  a fixed-function unit.
258  *
259  *  Make sure that gl_TessCoord is not an array.
260  *  Make sure that gl_TessCoord is not accessible for any of the vertices in
261  *  gl_in[].
262  *  Make sure that (u, v, w) coordinates are in range [0, 1] for all
263  *  tessellation primitive modes.
264  *  Make sure that the w coordinate is always zero for "quads" and "isolines"
265  *  tessellation primitive modes.
266  *
267  *  This test should be executed in two invocations, depending on the test type:
268  *
269  *  * Without a tessellation control shader, where the patch tessellation levels
270  *    are configured by using glPatchParameterfv() function (*);
271  *  * With a tessellation control shader used to configure the levels;
272  *
273  *  (*) Only applies to Desktop
274  *
275  **/
276 class TessellationShaderTessellationgl_TessCoord : public TestCaseBase
277 {
278 	static std::string getTypeName(_tessellation_test_type test_type);
279 
280 public:
281 	/* Public methods */
282 	TessellationShaderTessellationgl_TessCoord(Context& context, const ExtParameters& extParams,
283 											   _tessellation_test_type test_type);
284 
~TessellationShaderTessellationgl_TessCoord(void)285 	virtual ~TessellationShaderTessellationgl_TessCoord(void)
286 	{
287 	}
288 
289 	virtual void		  deinit(void);
290 	void				  initTest(void);
291 	virtual IterateResult iterate(void);
292 
293 private:
294 	/* Private type definitions */
295 	/** Defines a single test pass */
296 	typedef struct _test_descriptor
297 	{
298 		glw::GLint							n_patch_vertices;
299 		glw::GLuint							po_id;
300 		_tessellation_primitive_mode		primitive_mode;
301 		glw::GLuint							tc_id;
302 		glw::GLuint							te_id;
303 		glw::GLfloat						tess_level_inner[2];
304 		glw::GLfloat						tess_level_outer[4];
305 		_tessellation_test_type				type;
306 		_tessellation_shader_vertex_spacing vertex_spacing;
307 
308 		glw::GLint inner_tess_level_uniform_location;
309 		glw::GLint outer_tess_level_uniform_location;
310 
_test_descriptorglcts::TessellationShaderTessellationgl_TessCoord::_test_descriptor311 		_test_descriptor()
312 		{
313 			memset(tess_level_inner, 0, sizeof(tess_level_inner));
314 			memset(tess_level_outer, 0, sizeof(tess_level_outer));
315 
316 			n_patch_vertices = 0;
317 			po_id			 = 0;
318 			primitive_mode   = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
319 			tc_id			 = 0;
320 			te_id			 = 0;
321 			type			 = TESSELLATION_TEST_TYPE_UNKNOWN;
322 			vertex_spacing   = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
323 
324 			inner_tess_level_uniform_location = -1;
325 			outer_tess_level_uniform_location = -1;
326 		}
327 	} _test_descriptor;
328 
329 	/** Defines a vector of test passes */
330 	typedef std::vector<_test_descriptor> _tests;
331 	typedef _tests::const_iterator		  _tests_const_iterator;
332 
333 	/* Private methods */
334 	std::string getTCCode(glw::GLint n_patch_vertices);
335 
336 	std::string getTECode(_tessellation_shader_vertex_spacing vertex_spacing,
337 						  _tessellation_primitive_mode		  primitive_mode);
338 
339 	void deinitTestDescriptor(_test_descriptor& test);
340 
341 	void initTestDescriptor(_test_descriptor& test, _tessellation_shader_vertex_spacing vertex_spacing,
342 							_tessellation_primitive_mode primitive_mode, glw::GLint n_patch_vertices,
343 							const float* inner_tess_levels, const float* outer_tess_levels,
344 							_tessellation_test_type test_type);
345 
346 	/* Private variables */
347 	_tessellation_test_type m_test_type;
348 	glw::GLuint				m_bo_id;
349 	glw::GLuint				m_broken_ts_id;
350 	glw::GLuint				m_fs_id;
351 	glw::GLuint				m_vs_id;
352 	glw::GLuint				m_vao_id;
353 
354 	_tests					 m_tests;
355 	TessellationShaderUtils* m_utils_ptr;
356 };
357 
358 /* This test class implements the following test cases:
359  *
360  *   20. Make sure it is possible to use up to GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT/4
361  *       vec4 input variables in a tessellation control shader.
362  *       Make sure it is possible to use up to GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT/4
363  *       vec4 input variables in a tessellation evaluation shader.
364  *       This test should issue at least one draw call and verify the results to
365  *       make sure the implementation actually supports the maximums it reports.
366  *
367  *   21. Make sure it is possible to use up to GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT/4
368  *       vec4 per-vertex output variables in a tessellation control shader.
369  *       Make sure it is possible to use up to GL_MAX_TESS_PATCH_COMPONENTS_EXT/4
370  *       vec4 per-patch output variables in a tessellation control shader.
371  *       Make sure it is possible to use up to GL_MAX_TESS_PATCH_COMPONENTS_EXT/4
372  *       vec4 per-patch input variables in a tessellation evaluation shader.
373  *       Make sure it is possible to use up to GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT/4
374  *       vec4 per-vertex output variables in a tessellation evaluation shader.
375  *
376  *       NOTE: The test should separately check if a maximum number of per-vertex and
377  *             per-patch output variables used in a tessellation control shader works
378  *             correctly. This is due to a risk that, had both types been used at once,
379  *             the maximum amount of output components supported for tessellation
380  *             control shader GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT may
381  *             have been exceeded for implementations, for which the property is
382  *             not equal to:
383  *
384  *             (per-vertex output component count multiplied by output patch size +
385  *              + per-patch output component count).
386  *
387  *       This test should issue at least one draw call and verify the results to
388  *       make sure the implementation actually supports the maximums it reports.
389  *
390  *       Category: Functional Test.
391  *       Priority: Must-Have
392  *
393  *  The test is implemented by checking two different cases:
394  *  1) In first case, it makes sure it is possible to use up to:
395  *     - GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT     / 4 vec4 per-vertex variables in tessellation control shader,
396  *     - GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT    / 4 vec4 per-vertex variables in tessellation control shader,
397  *     - GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT  / 4 vec4 per-vertex variables in tessellation evaluation shader,
398  *     - GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation evaluation shader.
399  *
400  *  2) In second case, it makes sure it is possible to use up to:
401  *     - GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 vec4 per-patch variables in tessellation control shader,
402  *     - GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 vec4 per-patch variables in tessellation evaluation shader.
403  */
404 class TessellationShaderTessellationMaxInOut : public TestCaseBase
405 {
406 public:
407 	/* Public methods */
408 	TessellationShaderTessellationMaxInOut(Context& context, const ExtParameters& extParams);
409 
~TessellationShaderTessellationMaxInOut()410 	virtual ~TessellationShaderTessellationMaxInOut()
411 	{
412 	}
413 
414 	virtual void		  deinit(void);
415 	virtual IterateResult iterate(void);
416 
417 private:
418 	/* private methods */
419 	void initBufferObjects(void);
420 	void initProgramObjects(void);
421 	void initReferenceValues(void);
422 	void initTest(void);
423 	void retrieveGLConstantValues(void);
424 
425 	bool compareValues(char const* description, glw::GLfloat* reference_values, int n_reference_values);
426 
427 	/* private variables */
428 	glw::GLuint m_po_id_1; /* program object name for case 1 */
429 	glw::GLuint m_po_id_2; /* program object name for case 2 */
430 
431 	glw::GLuint m_fs_id;	/* fragment shader object name */
432 	glw::GLuint m_tcs_id_1; /* tessellation control shader object name for case 1 */
433 	glw::GLuint m_tcs_id_2; /* tessellation control shader object name for case 2 */
434 	glw::GLuint m_tes_id_1; /* tessellation evaluation shader object name for case 1 */
435 	glw::GLuint m_tes_id_2; /* tessellation evaluation shader object name for case 2 */
436 	glw::GLuint m_vs_id_1;  /* vertex shader object name for case 1 */
437 	glw::GLuint m_vs_id_2;  /* vertex shader object name for case 2 */
438 
439 	glw::GLuint m_tf_bo_id_1;		/* buffer object name */
440 	glw::GLuint m_tf_bo_id_2;		/* buffer object name */
441 	glw::GLuint m_patch_data_bo_id; /* buffer object name for patch submission */
442 
443 	glw::GLuint m_vao_id; /* vertex array object */
444 
445 	glw::GLint m_gl_max_tess_control_input_components_value;	 /* value of MAX_TESS_CONTROL_INPUT_COMPONENTS */
446 	glw::GLint m_gl_max_tess_control_output_components_value;	/* value of MAX_TESS_CONTROL_OUTPUT_COMPONENTS */
447 	glw::GLint m_gl_max_tess_evaluation_input_components_value;  /* value of MAX_TESS_EVALUATION_INPUT_COMPONENTS */
448 	glw::GLint m_gl_max_tess_evaluation_output_components_value; /* value of MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */
449 	glw::GLint
450 			   m_gl_max_transform_feedback_interleaved_components_value; /* value of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */
451 	glw::GLint m_gl_max_tess_patch_components_value;					 /* value of MAX_TESS_PATCH_COMPONENTS */
452 	glw::GLint m_gl_max_vertex_output_components_value;					 /* value of MAX_VERTEX_OUTPUT_COMPONENTS */
453 
454 	glw::GLfloat  m_ref_patch_attributes[4]; /* reference values for max per-patch attributes case 2 */
455 	glw::GLfloat* m_ref_vertex_attributes;   /* reference values for max per-vertex attributes case 1 */
456 
457 	static const char* m_fs_code;	/* fragment shader code */
458 	static const char* m_vs_code;	/* vertex shader code */
459 	static const char* m_tcs_code_1; /* tessellation control shader code for per vertex components check */
460 	static const char* m_tcs_code_2; /* tessellation control shader code per patch components check */
461 	static const char* m_tes_code_1; /* tessellation evaluation shader code per vertex components check */
462 	static const char* m_tes_code_2; /* tessellation evaluation shader code per patch components check */
463 
464 	char** m_tf_varyings_names; /* transform feedback varyings names array */
465 };
466 
467 } // namespace glcts
468 
469 #endif // _ESEXTCTESSELLATIONSHADERTESSELLATION_HPP
470