1 #ifndef _ESEXTCGEOMETRYSHADERINPUT_HPP
2 #define _ESEXTCGEOMETRYSHADERINPUT_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 <deque>
28 
29 namespace glcts
30 {
31 /** Implementation of test case 5.1. Test description follows:
32  *
33  *  Make sure that all output variables of a vertex shader can be accessed
34  *  under geometry shader's input array variables.
35  *
36  *  Category: API;
37  *            Functional Test.
38  *
39  *  Vertex shader should define:
40  *
41  *  - vec2 output variable named vs_gs_a;
42  *  - flat ivec4 output variable named vs_gs_b;
43  *
44  *  and set them to meaningful vector values (based on gl_VertexID).
45  *
46  *  Geometry shader should take triangles on input, output triangles (3
47  *  vertices will be emitted) and also define:
48  *
49  *  - vec2 output variable named gs_fs_a (and set it to vs_gs_a[i]);
50  *  - flat ivec4 output variable named gs_fs_b (and set it to vs_gs_b[i]);
51  *
52  *  where i is index of vertex.
53  *
54  *  gl_Position should be set as follows:
55  *
56  *  1st vertex) (-1, -1, 0, 1)
57  *  2nd vertex) (-1, 1, 0, 1)
58  *  3rd vertex) (1, 1, 0, 1)
59  *
60  *  Vertex attribute arrays should be configured so that vertex shader passes
61  *  meaningful values to the geometry shader.
62  *
63  *  Use Transform Feedback to check if geometry shader was passed the right
64  *  values. Draw a single triangle. The test passes if the captured data
65  *  matches the expected values.
66  **/
67 class GeometryShader_gl_in_ArrayContentsTest : public TestCaseBase
68 {
69 public:
70 	/* Public methods */
71 	GeometryShader_gl_in_ArrayContentsTest(Context& context, const ExtParameters& extParams, const char* name,
72 										   const char* description);
73 
~GeometryShader_gl_in_ArrayContentsTest()74 	virtual ~GeometryShader_gl_in_ArrayContentsTest()
75 	{
76 	}
77 
78 	virtual void		  deinit(void);
79 	virtual IterateResult iterate(void);
80 
81 private:
82 	/* Private methods */
83 	void initTest(void);
84 
85 	/* Private fields */
86 	/* Program and shader ids */
87 	glw::GLuint m_fragment_shader_id;
88 	glw::GLuint m_geometry_shader_sized_arrays_id;
89 	glw::GLuint m_geometry_shader_unsized_arrays_id;
90 	glw::GLuint m_program_object_sized_arrays_id;
91 	glw::GLuint m_program_object_unsized_arrays_id;
92 	glw::GLuint m_vertex_shader_id;
93 
94 	/* Shaders' code */
95 	static const glw::GLchar* const m_fragment_shader_code;
96 	static const glw::GLchar* const m_geometry_shader_code;
97 	static const glw::GLchar* const m_geometry_shader_preamble_code;
98 	static const glw::GLchar* const m_vertex_shader_code;
99 
100 	/* Buffer Object used to store output from transform feedback */
101 	glw::GLuint m_buffer_object_id;
102 
103 	/* Constants used to calculate and store size of buffer object, that will be used as transform feedback output */
104 	static const unsigned int m_buffer_size;
105 	static const unsigned int m_n_bytes_emitted_per_vertex;
106 	static const unsigned int m_n_emitted_primitives;
107 	static const unsigned int m_n_vertices_emitted_per_primitive;
108 
109 	/* Vertex array object ID */
110 	glw::GLuint m_vertex_array_object_id;
111 };
112 
113 /** Implementation of test case 5.2. Test description follows:
114  *
115  *  Make sure that length of gl_in array is correct for all input primitive
116  *  types accepted by a geometry shader.
117  *
118  *  Category: API;
119  *            Functional Test.
120  *
121  *  Consider a set of geometry shaders, where each geometry shader takes an
122  *  unique input primitive type, and the set - as a whole - covers all input
123  *  primitive types accepted by geometry shaders. Each geometry shader should
124  *  output a maximum of 1 point. They should define an output int variable
125  *  called in_array_size and set it to gl_in.length().
126  *
127  *  Using transform feed-back, the test should check whether all geometry
128  *  shaders are reported correct gl_in array size for all acceptable input
129  *  primitive types.
130  **/
131 class GeometryShader_gl_in_ArrayLengthTest : public TestCaseBase
132 {
133 public:
134 	/* Public methods */
135 	GeometryShader_gl_in_ArrayLengthTest(Context& context, const ExtParameters& extParams, const char* name,
136 										 const char* description);
137 
~GeometryShader_gl_in_ArrayLengthTest()138 	virtual ~GeometryShader_gl_in_ArrayLengthTest()
139 	{
140 	}
141 
142 	virtual void		  deinit(void);
143 	virtual void		  init(void);
144 	virtual IterateResult iterate(void);
145 
146 private:
147 	/* Private types */
148 	struct Case
149 	{
150 		/* Mode to be used for glDrawArrays() call */
151 		glw::GLenum draw_call_mode;
152 		/* Amount of vertices to be requested for glDrawArrays() call */
153 		glw::GLint draw_call_n_vertices;
154 		/* Transform feed-back mode to use before doing glDrawArrays() call */
155 		glw::GLenum tf_mode;
156 
157 		/* ID of a fragment shader to be used for the test case */
158 		glw::GLint fs_id;
159 		/* ID of a geometry shader to be used for the test case */
160 		glw::GLint gs_id;
161 		/* String defining input layout qualifier for the test case. */
162 		const glw::GLchar* input_body_part;
163 		/* String defining output layout qualifier for the test case. */
164 		const glw::GLchar* output_body_part;
165 		/** ID of a program object to be used for the test case */
166 		glw::GLint po_id;
167 		/** ID of a vertex shader to be used for the test case */
168 		glw::GLint vs_id;
169 
170 		/** Expected gl_in.length() value for the test case */
171 		glw::GLint expected_array_length;
172 	};
173 
174 	/* Type of container used to group all test cases */
175 	typedef std::deque<Case*> testContainer;
176 
177 	/* Private methods */
178 	void deinitCase(Case& info);
179 
180 	void initCase(Case& info, glw::GLenum draw_call_mode, glw::GLint draw_call_n_vertices,
181 				  glw::GLint expected_array_length, glw::GLenum tf_mode, const glw::GLchar* input_body_part,
182 				  const glw::GLchar* output_body_part);
183 
184 	void initCaseProgram(Case& info, const glw::GLchar** captured_varyings, glw::GLuint n_captured_varyings_size);
185 
186 	void resetCase(Case& info);
187 
188 	/* Private fields */
189 	/* Shaders */
190 	static const glw::GLchar* const m_vertex_shader_code;
191 
192 	static const glw::GLchar* const m_geometry_shader_code_input_points;
193 	static const glw::GLchar* const m_geometry_shader_code_input_lines;
194 	static const glw::GLchar* const m_geometry_shader_code_input_lines_with_adjacency;
195 	static const glw::GLchar* const m_geometry_shader_code_input_triangles;
196 	static const glw::GLchar* const m_geometry_shader_code_input_triangles_with_adjacency;
197 	static const glw::GLchar* const m_geometry_shader_code_main;
198 	static const glw::GLchar* const m_geometry_shader_code_output_line_strip;
199 	static const glw::GLchar* const m_geometry_shader_code_output_points;
200 	static const glw::GLchar* const m_geometry_shader_code_output_triangle_strip;
201 	static const glw::GLchar* const m_geometry_shader_code_preamble;
202 
203 	static const glw::GLchar* const m_fragment_shader_code;
204 
205 	/* Test cases */
206 	Case m_test_lines;
207 	Case m_test_lines_adjacency;
208 	Case m_test_lines_adjacency_to_line_strip;
209 	Case m_test_points;
210 	Case m_test_triangles;
211 	Case m_test_triangles_adjacency;
212 	Case m_test_triangles_adjacency_to_triangle_strip;
213 
214 	/* Set of test cases */
215 	testContainer m_tests;
216 
217 	/* Buffer Object used to store output from transform feedback */
218 	glw::GLuint m_buffer_object_id;
219 
220 	/* Constants used to calculate and store size of buffer object, that will be used as transform feedback output */
221 	static const glw::GLuint m_buffer_size;
222 	static const glw::GLuint m_max_primitive_emitted;
223 
224 	/* Vertex array object ID */
225 	glw::GLuint m_vertex_array_object_id;
226 };
227 
228 /** Implementation of test case 5.3. Test description follows:
229  *
230  *  Make sure geometry shader is passed gl_PointSize value as set by vertex
231  *  shader.
232  *
233  *  Category: API;
234  *            Functional Test.
235  *
236  *  NOTE: This test should be skipped if tested GLES implementation does not
237  *        support points of sufficiently large sizes.
238  *
239  *  Vertex shader should set gl_PointSize variable to 2*(gl_VertexID+1).
240  *
241  *  Geometry shader should take points on input and emit 1 point at most. It
242  *  should set gl_PointSize to 2*gl_in[0].gl_PointSize. The test will draw
243  *  two points, so to have these two points centered on the left and the right
244  *  side of the screen-space (assuming result draw buffer is 16px wide), set
245  *  gl_Position to:
246  *
247  *  1) (-1 + (4*(1/16))/2, 0, 0, 1) for the first point, given its point size
248  *    equal to 4;
249  *  2) ( 1 - (8*(1/16))/2, 0, 0, 1) for the second point, with its point size
250  *    set to 8;
251  *
252  *  Fragment shader should set the output variable to (1, 1, 1, 1), the
253  *  default clear color should be set to (0, 0, 0, 0).
254  *
255  *  Color attachment should have a resolution of 16px x 16px.
256  *
257  *  The test should clear the color buffer and draw two points. The test
258  *  passes if:
259  *
260  *  1) pixel at (2,  8) is (255, 255, 255, 255)
261  *  2) pixel at (14, 8) is (255, 255, 255, 255)
262  *  3) pixel at (6,  8) is (0,   0,   0,   0)
263  *
264  *  Assumption: glReadPixels() is called for GL_RGBA format and
265  *              GL_UNSIGNED_BYTE type.
266  **/
267 class GeometryShader_gl_PointSize_ValueTest : public TestCaseBase
268 {
269 public:
270 	/* Public methods */
271 	GeometryShader_gl_PointSize_ValueTest(Context& context, const ExtParameters& extParams, const char* name,
272 										  const char* description);
273 
~GeometryShader_gl_PointSize_ValueTest()274 	virtual ~GeometryShader_gl_PointSize_ValueTest()
275 	{
276 	}
277 
278 	virtual void		  deinit(void);
279 	virtual void		  init(void);
280 	virtual IterateResult iterate(void);
281 
282 private:
283 	/* Private fields */
284 	/* Program and shader ids */
285 	glw::GLuint m_fragment_shader_id;
286 	glw::GLuint m_geometry_shader_id;
287 	glw::GLuint m_program_object_id;
288 	glw::GLuint m_vertex_shader_id;
289 
290 	/* Shaders' code */
291 	static const glw::GLchar* const m_fragment_shader_code;
292 	static const glw::GLchar* const m_geometry_shader_code;
293 	static const glw::GLchar* const m_vertex_shader_code;
294 
295 	/* Vertex array object ID */
296 	glw::GLuint m_vertex_array_object_id;
297 
298 	/* Texture object ID */
299 	glw::GLuint m_color_texture_id;
300 
301 	/* Framebuffer object ID */
302 	glw::GLuint m_framebuffer_object_id;
303 
304 	/* Constants used to store properties of framebuffer's color attachment */
305 	static const glw::GLuint m_texture_height;
306 	static const glw::GLuint m_texture_pixel_size;
307 	static const glw::GLuint m_texture_width;
308 };
309 
310 /** Implementation of test case 5.4. Test description follows:
311  *
312  *  Make sure geometry shader is passed gl_Position value as set by vertex shader.
313  *
314  *  Category: API;
315  *            Functional Test.
316  *
317  *  Vertex shader should set gl_Position variable to
318  *  (gl_VertexID, gl_VertexID, 0, 1).
319  *
320  *  Geometry shader should take points on input and emit 1 point at most. It
321  *  should set gl_PointSize to 8. The test will draw eight points. The
322  *  geometry shader should set gl_Position to:
323  *
324  *           (-1 + 4/32 + gl_in[0].gl_Position / 4, 0, 0, 1)
325  *
326  *  Fragment shader should set the output variable to (1, 1, 1, 1), the
327  *  default clear color should be set to (0, 0, 0, 0).
328  *
329  *  Color attachment should have a resolution of 64px x 64px.
330  *
331  *  The test should clear the color buffer and draw eight points. The test
332  *  passes if centers of the rendered points at expected locations are lit.
333  **/
334 class GeometryShader_gl_Position_ValueTest : public TestCaseBase
335 {
336 public:
337 	/* Public methods */
338 	GeometryShader_gl_Position_ValueTest(Context& context, const ExtParameters& extParams, const char* name,
339 										 const char* description);
340 
~GeometryShader_gl_Position_ValueTest()341 	virtual ~GeometryShader_gl_Position_ValueTest()
342 	{
343 	}
344 
345 	virtual void		  deinit(void);
346 	virtual void		  init(void);
347 	virtual IterateResult iterate(void);
348 
349 private:
350 	/* Private fields */
351 	/* Program and shader ids */
352 	glw::GLuint m_fragment_shader_id;
353 	glw::GLuint m_geometry_shader_id;
354 	glw::GLuint m_program_object_id;
355 	glw::GLuint m_vertex_shader_id;
356 
357 	/* Shaders' code */
358 	static const glw::GLchar* const m_fragment_shader_code;
359 	static const glw::GLchar* const m_geometry_shader_code;
360 	static const glw::GLchar* const m_vertex_shader_code;
361 
362 	/* Vertex array object ID */
363 	glw::GLuint m_vertex_array_object_id;
364 
365 	/* Texture object ID */
366 	glw::GLuint m_color_texture_id;
367 
368 	/* Framebuffer object ID */
369 	glw::GLuint m_framebuffer_object_id;
370 
371 	/* Constants used to store properties of framebuffer's color attachment */
372 	static const glw::GLuint m_texture_height;
373 	static const glw::GLuint m_texture_pixel_size;
374 	static const glw::GLuint m_texture_width;
375 };
376 
377 } /* glcts */
378 
379 #endif // _ESEXTCGEOMETRYSHADERINPUT_HPP
380