• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ESEXTCTESSELLATIONSHADERTCTE_HPP
2 #define _ESEXTCTESSELLATIONSHADERTCTE_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 
34 /** A DEQP CTS test group that collects all tests that verify various
35  *  interactions between tessellation control and tessellation evaluation
36  *  shaders
37  */
38 class TessellationShaderTCTETests : public glcts::TestCaseGroupBase
39 {
40 public:
41 	/* Public methods */
42 	TessellationShaderTCTETests(glcts::Context& context, const ExtParameters& extParams);
43 
~TessellationShaderTCTETests(void)44 	virtual ~TessellationShaderTCTETests(void)
45 	{
46 	}
47 
48 	void init(void);
49 
50 private:
51 	/* Private methods */
52 	TessellationShaderTCTETests(const TessellationShaderTCTETests& other);
53 	TessellationShaderTCTETests& operator=(const TessellationShaderTCTETests& other);
54 };
55 
56 /** Implementation of Test Case 50
57  *
58  *  Make sure that tessellation control shader can correctly read per-vertex
59  *  values, as modified by a vertex shader. Verify per-vertex gl_Position
60  *  and gl_PointSize values are assigned values as in vertex shader.
61  *  Make sure that per-vertex & per-patch outputs written to in tessellation
62  *  control shader can be correctly read by tessellation evaluation shader.
63  *  Pay special attention to gl_Position and gl_PointSize.
64  *  Make sure that per-vertex output variables of a tessellation evaluation
65  *  shader can be correctly read by a geometry shader.
66  *
67  * Note: gl_PointSize should only be passed down the rendering pipeline and
68  *          then verified by the test if GL_EXT_tessellation_point_size
69  *          extension support is reported.
70  *
71  *  1. The test should run in three iterations:
72  *  1a. Vertex + TC + TE stages should be defined;
73  *  1b. Vertex + TC + TE + GS stages should be defined (if geometry
74  *      shaders are supported);
75  *  2. The test should be run for all three tessellator primitive types,
76  *     with inner and outer tessellation levels set to reasonably small
77  *     values but not equal to 1 for the levels that affect the tessellation
78  *     process for the primitive type considered.
79  *  3. Vertex shader should set:
80  *  3a. gl_Position to vec4(gl_VertexID);
81  *  3b. gl_PointSize to 1.0 / float(gl_VertexID);
82  *  3c. an output vec4 variable to:
83  *      vec4(gl_VertexID, gl_VertexID * 0.5, gl_VertexID * 0.25, gl_VertexID * 0.125);
84  *  3d. an outpt ivec4 variable to:
85  *      ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3);
86  *  4. TC shader should define corresponding input variables and patch
87  *     their contents through (for gl_InvocationID invocation) to
88  *     differently named output variables;
89  *     gl_Position and gl_PointSize values for the invocation
90  *     considered should also be forwarded.
91  *     One of the invocations for each patch should also set a vec4
92  *     and ivec4 per-patch variables to values as above, multiplied by two.
93  *  5. TE shader should define corresponding input variables and patch
94  *     their contents through to a differently named output variables;
95  *     gl_Position, gl_PointSize, gl_TessLevelOuter and gl_TessLevelInner
96  *     values for the primitive being processed should also be forwarded.
97  *     If TC is present in the pipeline, TE stage should also define
98  *     two new output variables and set them to per-patch variable
99  *     values, as set by TC.
100  *  6. Geometry shader should define corresponding input variables and
101  *     patch their contents through to a differently named output
102  *     variables;
103  *  7. Test implementation should retrieve the captured data once a single
104  *     instance of geometry is rendered and verify it.
105  *
106  **/
107 class TessellationShaderTCTEDataPassThrough : public TestCaseBase
108 {
109 public:
110 	/* Public methods */
111 	TessellationShaderTCTEDataPassThrough(Context& context, const ExtParameters& extParams);
112 
~TessellationShaderTCTEDataPassThrough(void)113 	virtual ~TessellationShaderTCTEDataPassThrough(void)
114 	{
115 	}
116 
117 	virtual void		  deinit();
118 	void				  initTest(void);
119 	virtual IterateResult iterate(void);
120 
121 private:
122 	/* Private type definitions */
123 	/* Stores all properties of a single test run */
124 	typedef struct _run
125 	{
126 		glw::GLuint fs_id;
127 		glw::GLuint gs_id;
128 		glw::GLuint po_id;
129 		glw::GLuint tcs_id;
130 		glw::GLuint tes_id;
131 		glw::GLuint vs_id;
132 
133 		_tessellation_primitive_mode primitive_mode;
134 		unsigned int				 n_result_vertices_per_patch;
135 
136 		std::vector<glw::GLfloat> result_tc_pointSize_data;
137 		std::vector<_vec4>		  result_tc_position_data;
138 		std::vector<_vec4>		  result_tc_value1_data;
139 		std::vector<_ivec4>		  result_tc_value2_data;
140 		std::vector<_vec4>		  result_te_patch_data;
141 		std::vector<glw::GLfloat> result_te_pointSize_data;
142 		std::vector<_vec4>		  result_te_position_data;
143 
144 		/* Constructor */
_runglcts::TessellationShaderTCTEDataPassThrough::_run145 		_run()
146 		{
147 			fs_id						= 0;
148 			gs_id						= 0;
149 			n_result_vertices_per_patch = 0;
150 			po_id						= 0;
151 			primitive_mode				= TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
152 			tcs_id						= 0;
153 			tes_id						= 0;
154 			vs_id						= 0;
155 		}
156 	} _run;
157 
158 	/* Encapsulates all test runs */
159 	typedef std::vector<_run>	 _runs;
160 	typedef _runs::const_iterator _runs_const_iterator;
161 
162 	/* Private methods */
163 	void deinitTestRun(_run& run);
164 	void executeTestRun(_run& run, _tessellation_primitive_mode primitive_mode, bool should_use_geometry_shader,
165 						bool should_pass_point_size_data_in_gs, bool should_pass_point_size_data_in_ts);
166 
167 	/* Private variables */
168 	glw::GLuint				 m_bo_id;
169 	const unsigned int		 m_n_input_vertices_per_run;
170 	_runs					 m_runs;
171 	TessellationShaderUtils* m_utils_ptr;
172 	glw::GLuint				 m_vao_id;
173 };
174 
175 /** Implementation of Test Case 52
176  *
177  *  This test should iterate over all vertex ordering / spacing / primitive /
178  *  point mode permutations, as well as over a number of inner/outer tessellation
179  *  level configurations.
180  *  The tessellation evaluation shaders used for the test should:
181  *
182  *  - Make sure that up to gl_MaxPatchVertices vertices' data can be read in
183  *    a tessellation evaluation shader.
184  *  - Make sure gl_Position and gl_PointSize per-vertex variables can be
185  *    accessed for all vertices.
186  *
187  *  The tessellation control shader used for the test should set iteration-
188  *  -specific properties and configure aforementioned per-vertex variables
189  *  accordingly.
190  *
191  *  Both pipeline objects and program objects should be used for the purpose
192  *  of the test. For each case, the test should verify that correct objects
193  *  defining tessellation control and tessellation stages are reported.
194  *  For program objects' case, the test should also confirm that valid shader
195  *  types are reported for TC and TE shader objects.
196  *  The test should also verify that no objects are assigned to either
197  *  stage by default.
198  *
199  *  The test should check that tessellation-specific properties are reported
200  *  correctly.
201  *
202  **/
203 class TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize : public TestCaseBase
204 {
205 public:
206 	/* Public methods */
207 	TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(Context& context, const ExtParameters& extParams);
208 
~TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(void)209 	virtual ~TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(void)
210 	{
211 	}
212 
213 	virtual void		  deinit();
214 	void				  initTest(void);
215 	virtual IterateResult iterate(void);
216 
217 private:
218 	/* Private type definitions */
219 	/** Describes a single test run */
220 	typedef struct _run
221 	{
222 		glw::GLuint fs_id;
223 		glw::GLuint fs_program_id;
224 		glw::GLuint pipeline_object_id;
225 		glw::GLuint po_id;
226 		glw::GLuint tc_id;
227 		glw::GLuint tc_program_id;
228 		glw::GLuint te_id;
229 		glw::GLuint te_program_id;
230 		glw::GLuint vs_id;
231 		glw::GLuint vs_program_id;
232 
233 		glw::GLfloat						 inner[2];
234 		glw::GLfloat						 outer[4];
235 		bool								 point_mode;
236 		_tessellation_primitive_mode		 primitive_mode;
237 		_tessellation_shader_vertex_ordering vertex_ordering;
238 		_tessellation_shader_vertex_spacing  vertex_spacing;
239 
240 		std::vector<float>  result_pointsize_data;
241 		std::vector<_vec4>  result_position_data;
242 		std::vector<_vec2>  result_value1_data;
243 		std::vector<_ivec4> result_value2_data;
244 
245 		/* Constructor */
_runglcts::TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize::_run246 		_run()
247 			: fs_id(0)
248 			, fs_program_id(0)
249 			, pipeline_object_id(0)
250 			, po_id(0)
251 			, tc_id(0)
252 			, tc_program_id(0)
253 			, te_id(0)
254 			, te_program_id(0)
255 			, vs_id(0)
256 			, vs_program_id(0)
257 			, point_mode(false)
258 			, primitive_mode(TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN)
259 			, vertex_ordering(TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN)
260 			, vertex_spacing(TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN)
261 		{
262 			memset(inner, 0, sizeof(inner));
263 			memset(outer, 0, sizeof(outer));
264 		}
265 	} _run;
266 
267 	/** Describes a set of test runs */
268 	typedef std::vector<_run>	 _runs;
269 	typedef _runs::const_iterator _runs_const_iterator;
270 
271 	/* Private methods */
272 	void deinitTestRun(_run& run);
273 	std::string getFragmentShaderCode(bool should_accept_pointsize_data);
274 
275 	std::string getTessellationControlShaderCode(bool should_pass_pointsize_data, const glw::GLfloat* inner_tess_levels,
276 												 const glw::GLfloat* outer_tess_levels);
277 
278 	std::string getTessellationEvaluationShaderCode(bool								 should_pass_pointsize_data,
279 													_tessellation_primitive_mode		 primitive_mode,
280 													_tessellation_shader_vertex_ordering vertex_ordering,
281 													_tessellation_shader_vertex_spacing  vertex_spacing,
282 													bool								 is_point_mode_enabled);
283 
284 	std::string getVertexShaderCode(bool should_pass_pointsize_data);
285 	void initTestRun(_run& run);
286 
287 	/* Private variables */
288 	glw::GLuint				 m_bo_id;
289 	glw::GLint				 m_gl_max_patch_vertices_value;
290 	glw::GLint				 m_gl_max_tess_gen_level_value;
291 	_runs					 m_runs;
292 	TessellationShaderUtils* m_utils_ptr;
293 	glw::GLuint				 m_vao_id;
294 };
295 
296 /** Implementation of Test Case 36
297  *
298  *  Make sure that values of gl_in[] in a tessellation evaluation shader are
299  *  taken from output variables of a tessellation control shader if one is
300  *  present. This test should verify that the values are not taken from
301  *  a vertex shader.
302  *
303  *  Technical details:
304  *
305  *  0. A program consisting of vertex, TC and TE stages should be considered.
306  *  1. Vertex shader should output a set of output variables of different types.
307  *  2. TC shader should define exactly the same set of output variables.
308  *     The data the shader writes to these variables must be different than
309  *     in the vertex shader's case.
310  *  3. TE shader should define these variables as input variables. It should
311  *     copy their values to a set of corresponding output variables, which
312  *     the test should then validate by means of Transform Feedback.
313  *
314  **/
315 class TessellationShaderTCTEgl_in : public TestCaseBase
316 {
317 public:
318 	/* Public methods */
319 	TessellationShaderTCTEgl_in(Context& context, const ExtParameters& extParams);
320 
~TessellationShaderTCTEgl_in(void)321 	virtual ~TessellationShaderTCTEgl_in(void)
322 	{
323 	}
324 
325 	virtual void		  deinit();
326 	void				  initTest(void);
327 	virtual IterateResult iterate(void);
328 
329 private:
330 	/* Private methods */
331 	void getXFBProperties(const glw::GLchar*** out_names, glw::GLint* out_n_names, glw::GLint* out_xfb_size);
332 
333 	/* Private variables */
334 	glw::GLuint m_bo_id;
335 	glw::GLuint m_fs_id;
336 	glw::GLuint m_po_id;
337 	glw::GLuint m_tcs_id;
338 	glw::GLuint m_tes_id;
339 	glw::GLuint m_vao_id;
340 	glw::GLuint m_vs_id;
341 };
342 
343 /**  Implementation of Test Case 37
344  *
345  *   Make sure that gl_TessLevelOuter[] and gl_TessLevelInner[] accessed from
346  *   tessellation evaluation shader hold values, as used in tessellation control
347  *   shader for a processed patch (assuming tessellation control shader is
348  *   present in the pipeline)
349  *   Make sure that gl_TessLevelOuter[] and gl_TessLevelInner[] accessed from
350  *   tessellation evaluation shader hold patch parameter values, if no
351  *   tessellation control shader is present in the pipeline.
352  *   Reported values should not be clamped and rounded, owing to active
353  *   vertex spacing mode.
354  *
355  *   Technical details:
356  *
357  *   0. The test should use two program objects: one defining a TC stage,
358  *      the other one should lack a tessellation control shader.
359  *   1. For the first case, the test implementation should check a couple
360  *      of different inner/outer tessellation level configurations by reading
361  *      them from an uniform that the test will update prior to doing a draw
362  *      call.
363  *      For the other case, the parameters can be modified using ES API.
364  *   2. TE should output inner and output tessellation levels to a varying,
365  *      for which Transform Feedback should be configured.
366  *   3. Test passes if tessellation levels in TE stage match the ones
367  *      defined in TC stage. Pay attention to making sure no clamping
368  *      or rounding occurs for any vertex spacing mode.
369  *
370  **/
371 class TessellationShaderTCTEgl_TessLevel : public TestCaseBase
372 {
373 public:
374 	/* Public methods */
375 	TessellationShaderTCTEgl_TessLevel(Context& context, const ExtParameters& extParams);
376 
~TessellationShaderTCTEgl_TessLevel(void)377 	virtual ~TessellationShaderTCTEgl_TessLevel(void)
378 	{
379 	}
380 
381 	virtual void		  deinit();
382 	void				  initTest(void);
383 	virtual IterateResult iterate(void);
384 
385 private:
386 	/* Private type definitions */
387 	typedef struct _test_descriptor
388 	{
389 		_tessellation_test_type				type;
390 		_tessellation_shader_vertex_spacing vertex_spacing;
391 
392 		glw::GLuint fs_id;
393 		glw::GLuint po_id;
394 		glw::GLuint tcs_id;
395 		glw::GLuint tes_id;
396 		glw::GLuint vs_id;
397 
398 		glw::GLint inner_tess_levels_uniform_location;
399 		glw::GLint outer_tess_levels_uniform_location;
400 
_test_descriptorglcts::TessellationShaderTCTEgl_TessLevel::_test_descriptor401 		_test_descriptor()
402 		{
403 			fs_id  = 0;
404 			po_id  = 0;
405 			tcs_id = 0;
406 			tes_id = 0;
407 			vs_id  = 0;
408 
409 			inner_tess_levels_uniform_location = 0;
410 			outer_tess_levels_uniform_location = 0;
411 
412 			type		   = TESSELLATION_TEST_TYPE_COUNT;
413 			vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
414 		}
415 	} _test_descriptor;
416 
417 	typedef std::vector<_test_descriptor> _tests;
418 	typedef _tests::const_iterator		  _tests_const_iterator;
419 
420 	/* Private methods */
421 	void deinitTestDescriptor(_test_descriptor* test_ptr);
422 
423 	void initTestDescriptor(_tessellation_test_type test_type, _test_descriptor* out_test_ptr,
424 							_tessellation_shader_vertex_spacing vertex_spacing_mode);
425 
426 	/* Private variables */
427 	glw::GLint m_gl_max_tess_gen_level_value;
428 
429 	glw::GLuint m_bo_id;
430 	_tests		m_tests;
431 	glw::GLuint m_vao_id;
432 };
433 
434 /**  Implementation of Test Case 35
435  *
436  *   Make sure that the number of vertices in input patch of a tessellation
437  *   evaluation shader is:
438  *
439  *   * fixed and equal to tessellation control shader output patch size parameter
440  *     from the time the program object was linked last time, should tessellation
441  *     control shader be present in the pipeline;
442  *   * equal to patch size parameter at the time of a draw call, if there
443  *     is no tessellation control shader present in the pipeline.
444  *
445  *   Technical details:
446  *
447  *   0. Apart from the two cases described in the test summary, the implementation
448  *      should also iterate over a number of different patch size values.
449  *   1. TE shader should save gl_PatchVerticesIn.length() in an output
450  *      variable. This variable should be XFBed to a buffer object and then
451  *      verified in the actual test.
452  *
453  **/
454 class TessellationShaderTCTEgl_PatchVerticesIn : public TestCaseBase
455 {
456 public:
457 	/* Public methods */
458 	TessellationShaderTCTEgl_PatchVerticesIn(Context& context, const ExtParameters& extParams);
459 
~TessellationShaderTCTEgl_PatchVerticesIn(void)460 	virtual ~TessellationShaderTCTEgl_PatchVerticesIn(void)
461 	{
462 	}
463 
464 	virtual void		  deinit();
465 	void				  initTest(void);
466 	virtual IterateResult iterate(void);
467 
468 private:
469 	/* Private type definitions */
470 	typedef struct _test_descriptor
471 	{
472 		_tessellation_test_type type;
473 
474 		glw::GLuint fs_id;
475 		glw::GLuint po_id;
476 		glw::GLuint tcs_id;
477 		glw::GLuint tes_id;
478 		glw::GLuint vs_id;
479 
480 		unsigned int input_patch_size;
481 
_test_descriptorglcts::TessellationShaderTCTEgl_PatchVerticesIn::_test_descriptor482 		_test_descriptor()
483 		{
484 			fs_id  = 0;
485 			po_id  = 0;
486 			tcs_id = 0;
487 			tes_id = 0;
488 			vs_id  = 0;
489 
490 			input_patch_size = 0;
491 			type			 = TESSELLATION_TEST_TYPE_COUNT;
492 		}
493 	} _test_descriptor;
494 
495 	typedef std::vector<_test_descriptor> _tests;
496 	typedef _tests::const_iterator		  _tests_const_iterator;
497 
498 	/* Private methods */
499 	void deinitTestDescriptor(_test_descriptor* test_ptr);
500 	void initTestDescriptor(_tessellation_test_type test_type, _test_descriptor* out_test_ptr,
501 							unsigned int input_patch_size);
502 
503 	/* Private variables */
504 	glw::GLint m_gl_max_patch_vertices_value;
505 
506 	glw::GLuint m_bo_id;
507 	_tests		m_tests;
508 	glw::GLuint m_vao_id;
509 };
510 
511 } // namespace glcts
512 
513 #endif // _ESEXTCTESSELLATIONSHADERTCTE_HPP
514