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