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