Home | History | Annotate | Download | only in tessellation_shader
      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 
     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 
     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 
    111 		_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 
    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 
    206 		_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 
    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 
    311 		_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 
    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