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
28namespace 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 */
204struct 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 */
213struct 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 */
223class AdjacencyGridStrip
224{
225public:
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 */
236class AdjacencyGridTriangle
237{
238public:
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 */
249class AdjacencyGrid
250{
251public:
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 */
269class AdjacencyTestData
270{
271public:
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 */
292class GeometryShaderAdjacency : public TestCaseBase
293{
294public:
295	/* Public methods */
296	GeometryShaderAdjacency(Context& context, const ExtParameters& extParams, const char* name, const char* description,
297							AdjacencyTestData& testData);
298
299	virtual ~GeometryShaderAdjacency()
300	{
301	}
302
303	virtual void		  deinit(void);
304	virtual IterateResult iterate(void);
305
306protected:
307	/* Protected methods */
308	void		initTest(void);
309	const char* getFragmentShaderCode();
310	const char* getVertexShaderCode();
311
312private:
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