1 #ifndef _ESEXTCTESSELLATIONSHADERINVARIANCE_HPP
2 #define _ESEXTCTESSELLATIONSHADERINVARIANCE_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 "glwEnums.hpp"
30 #include "tcuDefs.hpp"
31 
32 namespace glcts
33 {
34 
35 /** A DEQP CTS test group that collects all tests that verify invariance
36  *  conformance.
37  */
38 class TessellationShaderInvarianceTests : public glcts::TestCaseGroupBase
39 {
40 public:
41     /* Public methods */
42     TessellationShaderInvarianceTests(glcts::Context &context, const ExtParameters &extParams);
43 
~TessellationShaderInvarianceTests(void)44     virtual ~TessellationShaderInvarianceTests(void)
45     {
46     }
47 
48     virtual void init(void);
49 
50 private:
51     /* Private methods */
52     TessellationShaderInvarianceTests(const TessellationShaderInvarianceTests &other);
53     TessellationShaderInvarianceTests &operator=(const TessellationShaderInvarianceTests &other);
54 };
55 
56 /** Base class that provides shared invariance test implementation. Invariance
57  *  rule test need only to implement the abstract methods.
58  **/
59 class TessellationShaderInvarianceBaseTest : public TestCaseBase
60 {
61 public:
62     /* Public methods */
63     TessellationShaderInvarianceBaseTest(Context &context, const ExtParameters &extParams, const char *name,
64                                          const char *description);
65 
~TessellationShaderInvarianceBaseTest(void)66     virtual ~TessellationShaderInvarianceBaseTest(void)
67     {
68     }
69 
70     virtual void deinit(void);
71     virtual IterateResult iterate(void);
72 
73 protected:
74     /* Protected variables */
75     TessellationShaderUtils *m_utils_ptr;
76 
77     virtual void executeDrawCall(unsigned int n_iteration);
78     virtual unsigned int getAmountOfIterations() = 0;
79     virtual unsigned int getDrawCallCountArgument();
80     virtual std::string getFSCode(unsigned int n_iteration);
81     virtual const char *getInnerTessLevelUniformName();
82     virtual const char *getOuterTessLevelUniformName();
83 
84     virtual void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels,
85                                         float *out_outer_tess_levels, bool *out_point_mode,
86                                         _tessellation_primitive_mode *out_primitive_mode,
87                                         _tessellation_shader_vertex_ordering *out_vertex_ordering,
88                                         unsigned int *out_result_buffer_size) = 0;
89 
90     virtual std::string getTCCode(unsigned int n_iteration);
91     virtual std::string getTECode(unsigned int n_iteration) = 0;
92     virtual std::string getVSCode(unsigned int n_iteration);
93 
94     virtual void getXFBProperties(unsigned int n_iteration, unsigned int *out_n_names, const char ***out_names);
95 
96     virtual void verifyResultDataForIteration(unsigned int n_iteration, const void *data);
97 
98     virtual void verifyResultData(const void **all_iterations_data);
99 
100 private:
101     /* Private type definitions */
102 
103     /* Private methods */
104     void initTest();
105 
106     /* Private variables */
107     typedef struct _test_program
108     {
109         glw::GLuint po_id;
110 
111         glw::GLuint inner_tess_level_uniform_location;
112         glw::GLuint outer_tess_level_uniform_location;
113 
114     } _test_program;
115 
116     /* Defines a vector of program objects. Index corresponds to iteration index */
117     typedef std::vector<_test_program> _programs;
118     typedef _programs::const_iterator _programs_const_iterator;
119     typedef _programs::iterator _programs_iterator;
120 
121     glw::GLuint m_bo_id;
122     _programs m_programs;
123     glw::GLuint m_qo_tfpw_id;
124     glw::GLuint m_vao_id;
125 };
126 
127 /** Implementation of Test Case 42
128  *
129  *  Make sure that invariance rule 1 is adhered to. Using a program object
130  *  consisting of a fragment/tessellation control/tessellation evaluation/
131  *  vertex shaders, render three points/lines/triangles (A, B, C) and
132  *  store vertices output by the tessellation evaluation shader.  Then render
133  *  the geometry in (B, C, A) order, using the same program object. Test
134  *  passes if vertices stored in two different iterations for the same
135  *  triangle are identical. Owing to rule 8, assume zero epsilon.
136  **/
137 class TessellationShaderInvarianceRule1Test : public TessellationShaderInvarianceBaseTest
138 {
139 public:
140     /* Public methods */
141     TessellationShaderInvarianceRule1Test(Context &context, const ExtParameters &extParams);
142     virtual ~TessellationShaderInvarianceRule1Test();
143 
144 protected:
145     /* Protected methods */
146     unsigned int getAmountOfIterations();
147     unsigned int getDrawCallCountArgument();
148 
149     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
150                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
151                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
152                                 unsigned int *out_result_buffer_size);
153 
154     std::string getTECode(unsigned int n_iteration);
155     void verifyResultData(const void **all_iterations_data);
156 };
157 
158 /** Implementation of Test Case 43
159  *
160  *  Make sure that invariance rule 2 is adhered to. Using a program object
161  *  consisting of a fragment/tessellation control/tessellation evaluation/
162  *  vertex shaders, render a number of full-screen triangles/quads, each
163  *  instance rendered with different inner tessellation level but identical
164  *  outer tessellation level and spacing input layout qualifiers. Test passes
165  *  if outer edge's vertices are the same for both types of geometry
166  *  (each type considered separately).
167  **/
168 class TessellationShaderInvarianceRule2Test : public TessellationShaderInvarianceBaseTest
169 {
170 public:
171     /* Public methods */
172     TessellationShaderInvarianceRule2Test(Context &context, const ExtParameters &extParams);
173     virtual ~TessellationShaderInvarianceRule2Test();
174 
175 protected:
176     /* Protected methods */
177     unsigned int getAmountOfIterations();
178 
179     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
180                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
181                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
182                                 unsigned int *out_result_buffer_size);
183 
184     std::string getTECode(unsigned int n_iteration);
185     void verifyResultData(const void **all_iterations_data);
186 
187 private:
188     /* Private variables */
189     unsigned int m_n_tessellated_vertices[4 /* iterations in total */];
190 };
191 
192 /** Implementation of Test Case 44
193  *
194  *  Make sure that invariance rule 3 is adhered to. Using a program object
195  *  consisting of a fragment/tessellation control/tessellation evaluation/
196  *  vertex shaders, tessellate a number of triangles/quads/isolines geometry
197  *  with different inner/outer/vertex spacing input layout qualifiers.
198  *  Capture vertices generated by tessellation evaluation stage and make sure
199  *  that generated vertices are symmetrical. Owing to rule 8, assume zero
200  *  epsilon.
201  **/
202 class TessellationShaderInvarianceRule3Test : public TessellationShaderInvarianceBaseTest
203 {
204 public:
205     /* Public methods */
206     TessellationShaderInvarianceRule3Test(Context &context, const ExtParameters &extParams);
207     virtual ~TessellationShaderInvarianceRule3Test();
208 
209 protected:
210     /* Protected methods */
211     unsigned int getAmountOfIterations();
212 
213     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
214                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
215                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
216                                 unsigned int *out_result_buffer_size);
217 
218     std::string getTECode(unsigned int n_iteration);
219 
220     void verifyResultDataForIteration(unsigned int n_iteration, const void *data);
221 
222 private:
223     /* Private type definitions */
224     typedef struct _test_iteration
225     {
226         glw::GLfloat inner_tess_levels[2];
227         glw::GLfloat outer_tess_levels[4];
228         _tessellation_primitive_mode primitive_mode;
229         _tessellation_shader_vertex_spacing vertex_spacing;
230 
231         unsigned int n_vertices;
232 
_test_iterationglcts::TessellationShaderInvarianceRule3Test::_test_iteration233         _test_iteration()
234         {
235             memset(inner_tess_levels, 0, sizeof(inner_tess_levels));
236             memset(outer_tess_levels, 0, sizeof(outer_tess_levels));
237 
238             primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
239             vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
240 
241             n_vertices = 0;
242         }
243     } _test_iteration;
244 
245     typedef std::vector<_test_iteration> _test_iterations;
246     typedef _test_iterations::const_iterator _test_iterations_const_iterator;
247 
248     /* Private methods */
249     void deinitTestIterations();
250     void initTestIterations();
251 
252     /* Private fields */
253     _test_iterations m_test_iterations;
254 };
255 
256 /** Implementation of Test Case 45
257  *
258  *  Make sure that invariance rule 4 is adhered to. Using a program object
259  *  consisting of a fragment/tessellation control/tessellation evaluation/
260  *  vertex shaders, tessellate a number of triangular and quad geometry with
261  *  different inner tessellation level input layout qualifiers.
262  *  Capture vertices generated by tessellation evaluation stage and make sure
263  *  that all sets of vertices generated when subdividing outer edges are
264  *  independent of the specific edge subdivided.
265  *
266  *  Technical details:
267  *
268  *  1. The test should use a number of different inner+outer
269  *     tessellation levels+vertex spacing mode configuration
270  *     combinations, each resulting in a different vertex set for
271  *     the generator primitive type considered.
272  *     In first iteration, it should draw a screen quad, and
273  *     in the other a triangle should be rendered.
274  *  2. The test should capture vertices output in TE stage. The
275  *     rasterizer discard mode can be enabled, as the test is not
276  *     expected to analyse visual output.
277  *  3. For quad tessellation, the test should identify vertices
278  *     generated for top outer edge and make sure that remaining
279  *     outer edges of the quad are built of vertices that conform
280  *     to the rule.
281  *  4. For triangular tessellation, the test should identify vertices
282  *     generated for one of the outer edges and then check if the other
283  *     two outer edges have been generated in conformance to the rule.
284  **/
285 class TessellationShaderInvarianceRule4Test : public TessellationShaderInvarianceBaseTest
286 {
287 public:
288     /* Public methods */
289     TessellationShaderInvarianceRule4Test(Context &context, const ExtParameters &extParams);
290     virtual ~TessellationShaderInvarianceRule4Test();
291 
292 protected:
293     /* Protected methods */
294     unsigned int getAmountOfIterations();
295 
296     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
297                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
298                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
299                                 unsigned int *out_result_buffer_size);
300 
301     std::string getTECode(unsigned int n_iteration);
302 
303     void verifyResultDataForIteration(unsigned int n_iteration, const void *data);
304 
305 private:
306     /* Private type definitions */
307     typedef struct _test_iteration
308     {
309         glw::GLfloat inner_tess_levels[2];
310         glw::GLfloat outer_tess_levels[4];
311         _tessellation_primitive_mode primitive_mode;
312         _tessellation_shader_vertex_spacing vertex_spacing;
313 
314         unsigned int n_vertices;
315 
_test_iterationglcts::TessellationShaderInvarianceRule4Test::_test_iteration316         _test_iteration()
317         {
318             memset(inner_tess_levels, 0, sizeof(inner_tess_levels));
319             memset(outer_tess_levels, 0, sizeof(outer_tess_levels));
320 
321             primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
322             vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
323 
324             n_vertices = 0;
325         }
326     } _test_iteration;
327 
328     typedef std::vector<_test_iteration> _test_iterations;
329     typedef _test_iterations::const_iterator _test_iterations_const_iterator;
330 
331     /* Private methods */
332     void deinitTestIterations();
333     void initTestIterations();
334 
335     bool isVertexDefined(const float *vertex_data, unsigned int n_vertices, const float *vertex_data_seeked,
336                          unsigned int n_vertex_data_seeked_components);
337 
338     /* Private fields */
339     _test_iterations m_test_iterations;
340 };
341 
342 /** Implementation of Test Case 46
343  *
344  *  Make sure that Rule 5 is adhered to. Using a program object
345  *  consisting of a fragment/tessellation control/tessellation evaluation/
346  *  vertex shaders, tessellate a number of triangles/quads/isolines
347  *  geometry with different vertex ordering input layout qualifiers. Capture
348  *  vertices generated by tessellation evaluation stage and make sure that each
349  *  iteration defines exactly the same set of vertices, although in different
350  *  order.
351  *
352  **/
353 class TessellationShaderInvarianceRule5Test : public TessellationShaderInvarianceBaseTest
354 {
355 public:
356     /* Public methods */
357     TessellationShaderInvarianceRule5Test(Context &context, const ExtParameters &extParams);
358     virtual ~TessellationShaderInvarianceRule5Test();
359 
360 protected:
361     /* Protected methods */
362     unsigned int getAmountOfIterations();
363 
364     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
365                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
366                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
367                                 unsigned int *out_result_buffer_size);
368 
369     std::string getTECode(unsigned int n_iteration);
370     void verifyResultData(const void **all_iterations_data);
371 
372 private:
373     /* Private type definitions */
374     typedef struct _test_iteration
375     {
376         glw::GLfloat inner_tess_levels[2];
377         glw::GLfloat outer_tess_levels[4];
378         _tessellation_primitive_mode primitive_mode;
379         _tessellation_shader_vertex_ordering vertex_ordering;
380 
381         unsigned int n_vertices;
382 
_test_iterationglcts::TessellationShaderInvarianceRule5Test::_test_iteration383         _test_iteration()
384         {
385             memset(inner_tess_levels, 0, sizeof(inner_tess_levels));
386             memset(outer_tess_levels, 0, sizeof(outer_tess_levels));
387 
388             primitive_mode  = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
389             vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN;
390 
391             n_vertices = 0;
392         }
393     } _test_iteration;
394 
395     typedef std::vector<_test_iteration> _test_iterations;
396     typedef _test_iterations::const_iterator _test_iterations_const_iterator;
397 
398     /* Private methods */
399     void deinitTestIterations();
400     _test_iteration &getTestForIteration(unsigned int n_iteration);
401     void initTestIterations();
402     bool isVertexDefined(const float *vertex_data, unsigned int n_vertices, const float *vertex_data_seeked,
403                          unsigned int n_vertex_data_seeked_components);
404 
405     /* Private fields */
406     _test_iterations m_test_triangles_iterations;
407     _test_iterations m_test_quads_iterations;
408 };
409 
410 /**  Implementation of Test Case 47
411  *
412  *   Make sure that invariance rule 6 is adhered to. Using a program object
413  *   consisting of a fragment/tessellation control/tessellation evaluation/
414  *   vertex shaders, tessellate a number of triangles/quads geometry
415  *   with different inner tessellation levels/vertex spacing input layout qualifiers.
416  *   Capture vertices generated by tessellation evaluation stage and make sure
417  *   that all interior triangles generated during tessellation are identical
418  *   except for vertex and triangle order.
419  **/
420 class TessellationShaderInvarianceRule6Test : public TessellationShaderInvarianceBaseTest
421 {
422 public:
423     /* Public methods */
424     TessellationShaderInvarianceRule6Test(Context &context, const ExtParameters &extParams);
425     virtual ~TessellationShaderInvarianceRule6Test();
426 
427 protected:
428     /* Protected methods */
429     unsigned int getAmountOfIterations();
430 
431     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
432                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
433                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
434                                 unsigned int *out_result_buffer_size);
435 
436     std::string getTECode(unsigned int n_iteration);
437     void verifyResultData(const void **all_iterations_data);
438 
439 private:
440     /* Private type definitions */
441     typedef struct _test_iteration
442     {
443         glw::GLfloat inner_tess_levels[2];
444         glw::GLfloat outer_tess_levels[4];
445         _tessellation_primitive_mode primitive_mode;
446         _tessellation_shader_vertex_ordering vertex_ordering;
447 
448         unsigned int n_vertices;
449 
_test_iterationglcts::TessellationShaderInvarianceRule6Test::_test_iteration450         _test_iteration()
451         {
452             memset(inner_tess_levels, 0, sizeof(inner_tess_levels));
453             memset(outer_tess_levels, 0, sizeof(outer_tess_levels));
454 
455             primitive_mode  = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
456             vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN;
457 
458             n_vertices = 0;
459         }
460     } _test_iteration;
461 
462     typedef std::vector<_test_iteration> _test_iterations;
463     typedef _test_iterations::const_iterator _test_iterations_const_iterator;
464 
465     /* Private methods */
466     void deinitTestIterations();
467     _test_iteration &getTestForIteration(unsigned int n_iteration);
468     void initTestIterations();
469 
470     /* Private fields */
471     _test_iterations m_test_triangles_iterations;
472     _test_iterations m_test_quads_iterations;
473 };
474 
475 /**  Implementation of Test Case 48
476  *
477  *   Make sure that invariance rule 7 is adhered to. Using a program object
478  *   consisting of a fragment/tessellation control/tessellation evaluation/
479  *   vertex shaders, tessellate a number of triangles/quads geometry
480  *   with different vertex spacing input layout qualifiers. For each such
481  *   case, the test should verify that modification of a single outer tessellation
482  *   level only affects tessellation coordinates generated for a corresponding
483  *   edge. Verification should be carried out by capturing vertices generated for
484  *   tessellation evaluation stage and making sure that each iteration defines
485  *   exactly the same set of triangles connecting inner and outer edge of the
486  *   tessellated geometry for all but the modified edge.
487  **/
488 class TessellationShaderInvarianceRule7Test : public TessellationShaderInvarianceBaseTest
489 {
490 public:
491     /* Public methods */
492     TessellationShaderInvarianceRule7Test(Context &context, const ExtParameters &extParams);
493     virtual ~TessellationShaderInvarianceRule7Test();
494 
495 protected:
496     /* Protected methods */
497     unsigned int getAmountOfIterations();
498 
499     void getIterationProperties(unsigned int n_iteration, float *out_inner_tess_levels, float *out_outer_tess_levels,
500                                 bool *out_point_mode, _tessellation_primitive_mode *out_primitive_mode,
501                                 _tessellation_shader_vertex_ordering *out_vertex_ordering,
502                                 unsigned int *out_result_buffer_size);
503 
504     std::string getTECode(unsigned int n_iteration);
505     void verifyResultData(const void **all_iterations_data);
506 
507 private:
508     /* Private type definitions */
509     typedef struct _test_iteration
510     {
511         glw::GLfloat inner_tess_levels[2];
512         glw::GLfloat outer_tess_levels[4];
513         _tessellation_primitive_mode primitive_mode;
514         _tessellation_shader_vertex_ordering vertex_ordering;
515 
516         bool is_base_iteration;
517         unsigned int n_modified_outer_tess_level;
518         unsigned int n_vertices;
519 
_test_iterationglcts::TessellationShaderInvarianceRule7Test::_test_iteration520         _test_iteration()
521         {
522             memset(inner_tess_levels, 0, sizeof(inner_tess_levels));
523             memset(outer_tess_levels, 0, sizeof(outer_tess_levels));
524 
525             primitive_mode  = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
526             vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN;
527 
528             is_base_iteration           = false;
529             n_modified_outer_tess_level = 0;
530             n_vertices                  = 0;
531         }
532     } _test_iteration;
533 
534     typedef std::vector<_test_iteration> _test_iterations;
535     typedef _test_iterations::const_iterator _test_iterations_const_iterator;
536 
537     /* Private methods */
538     void deinitTestIterations();
539 
540     unsigned int getTestIterationIndex(bool is_triangles_iteration, const float *inner_tess_levels,
541                                        const float *outer_tess_levels,
542                                        _tessellation_shader_vertex_ordering vertex_ordering,
543                                        unsigned int n_modified_outer_tess_level);
544 
545     _test_iteration &getTestForIteration(unsigned int n_iteration);
546     void initTestIterations();
547 
548     bool isTriangleDefinedInVertexDataSet(const float *base_triangle_data, const float *vertex_data,
549                                           unsigned int vertex_data_n_vertices);
550 
551     bool isVertexDefined(const float *vertex_data, unsigned int n_vertices, const float *vertex_data_seeked,
552                          unsigned int n_vertex_data_seeked_components);
553 
554     /* Private fields */
555     _test_iterations m_test_triangles_iterations;
556     _test_iterations m_test_quads_iterations;
557 };
558 
559 } // namespace glcts
560 
561 #endif // _ESEXTCTESSELLATIONSHADERINVARIANCE_HPP
562