1 #ifndef _ESEXTCTESSELLATIONSHADERQUADS_HPP
2 #define _ESEXTCTESSELLATIONSHADERQUADS_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 #include <vector>
31 
32 namespace glcts
33 {
34 /** A DEQP CTS test group that collects all tests that verify quad
35  *  tessellation.
36  */
37 class TessellationShaderQuadsTests : public glcts::TestCaseGroupBase
38 {
39 public:
40     /* Public methods */
41     TessellationShaderQuadsTests(glcts::Context &context, const ExtParameters &extParams);
~TessellationShaderQuadsTests(void)42     virtual ~TessellationShaderQuadsTests(void)
43     {
44     }
45 
46     void init(void);
47 
48 private:
49     /* Private methods */
50     TessellationShaderQuadsTests(const TessellationShaderQuadsTests &other);
51     TessellationShaderQuadsTests &operator=(const TessellationShaderQuadsTests &other);
52 };
53 
54 /** Implementation of Test Case 32
55  *
56  *  Consider quad tessellation.
57  *  Make sure that only a single triangle pair covering the outer rectangle
58  *  is generated, if both clamped inner tessellation levels and all four
59  *  clamped outer tessellation levels are exactly one.
60  *
61  *  Consider a few different inner and outer tessellation level pairs
62  *  combined with vertex spacing modes that clamp/round to the values as
63  *  per test summary.
64  *
65  *  The test should capture vertices output in TE stage, given the
66  *  pre-conditions described in the test summary, and then verify vertex
67  *  locations. Assume epsilon 1e-5. A single triangle should be drawn.
68  *
69  **/
70 class TessellationShaderQuadsDegenerateCase : public TestCaseBase
71 {
72 public:
73     /* Public methods */
74     TessellationShaderQuadsDegenerateCase(Context &context, const ExtParameters &extParams);
75 
~TessellationShaderQuadsDegenerateCase(void)76     virtual ~TessellationShaderQuadsDegenerateCase(void)
77     {
78     }
79 
80     virtual void deinit(void);
81     void initTest(void);
82     virtual IterateResult iterate(void);
83 
84 private:
85     /* Private type definitions */
86     typedef struct _run
87     {
88         float inner[2];
89         float outer[4];
90         _tessellation_shader_vertex_spacing vertex_spacing;
91 
92         std::vector<char> data;
93         unsigned int n_vertices;
94 
_runglcts::TessellationShaderQuadsDegenerateCase::_run95         _run()
96         {
97             memset(inner, 0, sizeof(inner));
98             memset(outer, 0, sizeof(outer));
99 
100             n_vertices     = 0;
101             vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
102         }
103     } _run;
104 
105     typedef std::vector<_run> _runs;
106     typedef _runs::const_iterator _runs_const_iterator;
107 
108     /* Private variables */
109     glw::GLuint m_vao_id;
110     _runs m_runs;
111     TessellationShaderUtils *m_utils;
112 };
113 
114 /** Implementation of Test Case 33
115  *
116  *  Consider quad tessellation.
117  *  Make sure that if either clamped inner tessellation level is set to one, that
118  *  tessellation level is treated as though it were originally specified as
119  *  2, which would rounded up to result in a two- or three-segment subdivision
120  *  according to the tessellation spacing.
121  *
122  *  Technical details:
123  *
124  *  1. Consider all vertex spacing modes. For each vertex spacing mode, take
125  *     a level value that, given the mode active, would clamp to one. In first
126  *     iteration use that value for the first inner tessellation level
127  *     (setting the other inner tessellation level to any valid value), then
128  *     in the other iteration swap the second inner tessellation level with
129  *     the first inner tessellation level.
130  *     For equal and fractional even vertex spacing modes used for every
131  *     inner tessellation configuration, do:
132  *  1a. Using any valid outer tessellation configuration, "draw" four patches.
133  *      Capture output vertices from TE stage.
134  *  1b. Using the same outer tessellation configuration, but replacing the
135  *      rounding value to the value we actually expect it to round to for the
136  *      given iteration, again capture output vertices from TE stage.
137  *  1c. Iteration passes if primitives captured are identical in both cases.
138  *      Assume epsilon 1e-5.
139  *
140  *     In case of fractional odd vertex spacing, verify that two marker
141  *     triangles capping the opposite ends of the inner quad tessellation
142  *     region exist. More information about the technique (and the rationale)
143  *     can be found in
144  *     TessellationShaderQuadsInnerTessellationLevelRounding::iterate().
145  *
146  *  2. Test passes if all iterations passed successfully.
147  *
148  **/
149 class TessellationShaderQuadsInnerTessellationLevelRounding : public TestCaseBase
150 {
151 public:
152     /* Public methods */
153     TessellationShaderQuadsInnerTessellationLevelRounding(Context &context, const ExtParameters &extParams);
154 
~TessellationShaderQuadsInnerTessellationLevelRounding(void)155     virtual ~TessellationShaderQuadsInnerTessellationLevelRounding(void)
156     {
157     }
158 
159     virtual void deinit(void);
160     void initTest(void);
161     virtual IterateResult iterate(void);
162 
163 private:
164     /* Private type definitions */
165     typedef struct _run
166     {
167         float set1_inner[2];
168         float set1_outer[4];
169         float set2_inner[2];
170         float set2_outer[4];
171         _tessellation_shader_vertex_spacing vertex_spacing;
172 
173         std::vector<char> set1_data;
174         std::vector<char> set2_data;
175         unsigned int n_vertices;
176 
_runglcts::TessellationShaderQuadsInnerTessellationLevelRounding::_run177         _run()
178         {
179             memset(set1_inner, 0, sizeof(set1_inner));
180             memset(set1_outer, 0, sizeof(set1_outer));
181             memset(set2_inner, 0, sizeof(set2_inner));
182             memset(set2_outer, 0, sizeof(set2_outer));
183 
184             n_vertices     = 0;
185             vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
186         }
187     } _run;
188 
189     typedef std::vector<_run> _runs;
190     typedef _runs::const_iterator _runs_const_iterator;
191 
192     /* Private methods */
193     std::vector<_vec2> getUniqueTessCoordinatesFromVertexDataSet(const float *raw_data,
194                                                                  const unsigned int n_raw_data_vertices);
195 
196     /* Private variables */
197     glw::GLuint m_vao_id;
198     _runs m_runs;
199     TessellationShaderUtils *m_utils;
200 };
201 
202 } // namespace glcts
203 
204 #endif // _ESEXTCTESSELLATIONSHADERQUADS_HPP
205