1 #ifndef _ESEXTCGEOMETRYSHADERADJACENCY_HPP
2 #define _ESEXTCGEOMETRYSHADERADJACENCY_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 
28 namespace glcts
29 {
30 /* Test Implementation of "Group 2" from CTS_EXT_geometry_shader. Description follows:
31  *
32  * 1. Make sure that draw calls properly accept and pass the "lines with
33  *    adjacency" data to a geometry shader. The geometry shader should then
34  *    forward adjacent line segments into one transform feedback buffer object
35  *    and actual line segments into another one.
36  *
37  *    Category: API;
38  *              Functional Test
39  *
40  *    Create a program object and a fragment, geometry and vertex shader
41  *    objects, as well as a buffer object and a transform feedback object.
42  *
43  *    The vertex shader object can be boilerplate.
44  *
45  *    The geometry shader should define:
46  *
47  *    * output vec4 variable called out_adjacent_geometry;
48  *    * output vec4 variable called out_geometry;
49  *
50  *    It should take lines_adjacency data and emit two adjacent line segments
51  *    to out_adjacent_geometry variable and one "actual" line segment to
52  *    out_geometry. Since there will be two adjacent segments and only one
53  *    "actual" line segment, the missing line segment should use (0, 0, 0, 0)
54  *    coordinates for its start/end points.
55  *
56  *    The fragment shader object can have a boilerplate implementation.
57  *
58  *    Compile the shaders, attach them to the program object, link the program
59  *    object.
60  *
61  *    Generate and bind a vertex array object.
62  *
63  *    Initialize a buffer object (A) to have enough space to hold information
64  *    for 3 coordinates * 4  vertex locations * 2 (output primitive
65  *    type-specific data topology). The data should describe 4 lines (including
66  *    adjacency data) that - as a whole - make a rectangle from (-1, -1, 0) to
67  *    (1, 1, 0). The buffer data should then be bound to an attribute, whose
68  *    index corresponds to location of the input in variable. Enable the vertex
69  *    attribute array for this index.
70  *
71  *    Initialize a buffer object (B) to have enough space to hold result
72  *    adjacent data information.
73  *
74  *    Initialize a buffer object (C) to have enough space to hold result
75  *    geometry information.
76  *
77  *    Configure transform feedback so that it captures aforementioned data
78  *    written by geometry shader and stores:
79  *
80  *    * values stored into out_adjacency_geometry in buffer object B;
81  *    * values stored into out_geometry in buffer object C;
82  *
83  *    Use separate transform feedback mode. Enable transform feedback. Enable
84  *    rasterizer discard mode.
85  *
86  *    Finally, issue a draw call in GL_LINES_ADJACENCY_EXT mode for 8 points.
87  *
88  *    Map the buffer objects to client space. The test is assumed to have
89  *    passed if the mapped buffer objects contain correct data.
90  *
91  *    NOTE: This test should verify both arrayed and indexed draw calls work
92  *    correctly.
93  *
94  *
95  * 2. Make sure that draw calls properly accept and pass the "lines with
96  *    adjacency" data to a vertex shader without the adjacency information,
97  *    assuming there is no geometry shader defined for the pipeline.
98  *
99  *    Category: API;
100  *              Functional Test.
101  *
102  *    Create a program object and a fragment and vertex shader object, as well
103  *    as a buffer object and a transform feedback object.
104  *
105  *    The fragment shader object can have a boilerplate implementation.
106  *
107  *    The vertex shader object should define a single input vec3 variable
108  *    called in_vertex and a single output vec3 variable called out_vertex. It
109  *    should write data from in_vertex in an unchanged form to out_vertex.
110  *
111  *    Compile the shaders, attach them to the program object, link the program
112  *    object.
113  *
114  *    Bind the vertex array object.
115  *
116  *    Initialize a buffer object to have enough space to hold information about
117  *    3-component floating point-based 32 vertices. The data should represent 4
118  *    lines (including adjacency data) that - as a whole - make a rectangle
119  *    from (-1, -1, 0) to (1, 1, 0). The buffer data should then be bound to an
120  *    attribute, whose index corresponds to location of the input in variable.
121  *    Enable the vertex attribute array for this index..
122  *
123  *    Initialize another buffer object to have enough space to hold information
124  *    about at most 32 vertices, each consisting of 3 floating-point components.
125  *    Configure transform feed-back so that it captures data written by vertex
126  *    shader output variable to this buffer object. Enable transform feedback.
127  *    Enable rasterizer discard mode.
128  *
129  *    Finally, issue a draw call in GL_LINES_ADJACENCY_EXT mode for 8 points.
130  *
131  *    Map the buffer object to client space. The test is assumed to have passed
132  *    if the result data corresponds to locations of 8 vertices making up the
133  *    rectangle *without* the adjacency data.
134  *
135  *
136  * 3. Make sure that draw calls properly accept and pass the "line strips with
137  *    adjacency" data to a geometry shader, if there is one included in the
138  *    pipeline.
139  *
140  *    Category: API;
141  *              Functional Test.
142  *
143  *    Modify test case 2.1 accordingly to work on "line strips with adjacency"
144  *    data instead of "lines with adjacency" data.
145  *
146  *
147  * 4. Make sure that draw calls properly accept and pass the "line strips with
148  *    adjacency" data to a vertex shader without the adjacency information,
149  *    assuming there is no geometry shader defined for the pipeline.
150  *
151  *    Category: API;
152  *              Functional Test.
153  *
154  *    Modify test case 2.2 accordingly to work on "line strips with adjacency"
155  *    data instead of "lines with adjacency" data.
156  *
157  *
158  * 5. Make sure that draw calls properly accept and pass the "triangles with
159  *    adjacency" data to a geometry shader, if there is one included in the
160  *    pipeline.
161  *
162  *    Category: API;
163  *              Functional Test.
164  *
165  *    Modify test case 2.1 accordingly to work on "triangles with adjacency"
166  *    data instead of "lines with adjacency" data.
167  *
168  *
169  * 6. Make sure that draw calls properly accept and pass the "triangles with
170  *    adjacency" data to a vertex shader without the adjacency information,
171  *    assuming there is no geometry shader defined for the pipeline.
172  *
173  *    Category: API;
174  *              Functional Test.
175  *
176  *    Modify test case 2.2 accordingly to work on "triangles with adjacency"
177  *    data instead of "lines with adjacency" data
178  *
179  *
180  * 7. Make sure that draw calls properly accept and pass the "triangle strips
181  *    with adjacency" data to a geometry shader, if there is one included in
182  *    the pipeline.
183  *
184  *    Category: API;
185  *              Functional Test.
186  *
187  *    Modify test case 2.1 accordingly to work on "triangle strips with
188  *    adjacency" data instead of "lines with adjacency" data.
189  *
190  *
191  * 8. Make sure that draw calls properly accept and pass the "triangle strips
192  *    with adjacency" data to a vertex shader without the adjacency information,
193  *    assuming there is no geometry shader defined for the pipeline.
194  *
195  *    Category: API;
196  *              Functional Test.
197  *
198  *    Modify test case 2.2 accordingly to work on "triangle strips with
199  *    adjacency" data instead of "lines with adjacency" data.
200  *
201  **/
202 
203 /* Helper class for storing point data */
204 struct AdjacencyGridPoint
205 {
206 	/* Public variables */
207 	glw::GLuint  index;
208 	glw::GLfloat x;
209 	glw::GLfloat y;
210 };
211 
212 /* Helper class for storing line data */
213 struct AdjacencyGridLineSegment
214 {
215 	/* Public variables */
216 	AdjacencyGridPoint* m_point_end;
217 	AdjacencyGridPoint* m_point_end_adjacent;
218 	AdjacencyGridPoint* m_point_start;
219 	AdjacencyGridPoint* m_point_start_adjacent;
220 };
221 
222 /* Helper class for storing strip data */
223 class AdjacencyGridStrip
224 {
225 public:
226 	/* Public metods */
227 	AdjacencyGridStrip();
228 	virtual ~AdjacencyGridStrip();
229 
230 	/* Public variables */
231 	glw::GLuint			m_n_points;
232 	AdjacencyGridPoint* m_points;
233 };
234 
235 /* Helper class for storing triangle data */
236 class AdjacencyGridTriangle
237 {
238 public:
239 	/* Public variables */
240 	AdjacencyGridPoint* m_vertex_x;
241 	AdjacencyGridPoint* m_vertex_x_adjacent;
242 	AdjacencyGridPoint* m_vertex_y;
243 	AdjacencyGridPoint* m_vertex_y_adjacent;
244 	AdjacencyGridPoint* m_vertex_z;
245 	AdjacencyGridPoint* m_vertex_z_adjacent;
246 };
247 
248 /* Helper class for storing grid data */
249 class AdjacencyGrid
250 {
251 public:
252 	/* Public metods */
253 	AdjacencyGrid(void);
254 	virtual ~AdjacencyGrid(void);
255 
256 	/* Public variables */
257 	AdjacencyGridLineSegment* m_line_segments;
258 	AdjacencyGridStrip		  m_line_strip;
259 	AdjacencyGridPoint*		  m_points;
260 	AdjacencyGridTriangle*	m_triangles;
261 	AdjacencyGridStrip		  m_triangle_strip;
262 
263 	glw::GLuint m_n_points;
264 	glw::GLuint m_n_segments;
265 	glw::GLuint m_n_triangles;
266 };
267 
268 /* Helper class for storing test data */
269 class AdjacencyTestData
270 {
271 public:
272 	/* Public metods */
273 	AdjacencyTestData(void);
274 	virtual ~AdjacencyTestData(void);
275 
276 	/* Public variables */
277 	const char*	m_gs_code;
278 	glw::GLenum	m_mode;
279 	glw::GLuint	m_n_vertices;
280 	AdjacencyGrid* m_grid;
281 	glw::GLuint	m_geometry_bo_size;
282 	glw::GLuint	m_index_data_bo_size;
283 	glw::GLuint	m_vertex_data_bo_size;
284 	glw::GLfloat*  m_expected_adjacency_geometry;
285 	glw::GLfloat*  m_expected_geometry;
286 	glw::GLuint*   m_index_data;
287 	glw::GLenum	m_tf_mode;
288 	glw::GLfloat*  m_vertex_data;
289 };
290 
291 /* Test class implementation */
292 class GeometryShaderAdjacency : public TestCaseBase
293 {
294 public:
295 	/* Public methods */
296 	GeometryShaderAdjacency(Context& context, const ExtParameters& extParams, const char* name, const char* description,
297 							AdjacencyTestData& testData);
298 
~GeometryShaderAdjacency()299 	virtual ~GeometryShaderAdjacency()
300 	{
301 	}
302 
303 	virtual void		  deinit(void);
304 	virtual IterateResult iterate(void);
305 
306 protected:
307 	/* Protected methods */
308 	void		initTest(void);
309 	const char* getFragmentShaderCode();
310 	const char* getVertexShaderCode();
311 
312 private:
313 	/* Private variables */
314 	glw::GLuint		   m_adjacency_geometry_bo_id;
315 	glw::GLuint		   m_fs_id;
316 	glw::GLuint		   m_geometry_bo_id;
317 	glw::GLuint		   m_gs_id;
318 	glw::GLuint		   m_index_data_bo_id;
319 	glw::GLuint		   m_vertex_data_bo_id;
320 	glw::GLuint		   m_po_id;
321 	AdjacencyTestData& m_test_data;
322 	glw::GLuint		   m_vao_id;
323 	glw::GLuint		   m_vs_id;
324 
325 	/* Private constants */
326 	glw::GLuint  m_components_input;
327 	glw::GLfloat m_epsilon;
328 	glw::GLuint  m_position_attribute_location;
329 };
330 
331 } // namespace glcts
332 
333 #endif // _ESEXTCGEOMETRYSHADERADJACENCY_HPP
334