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 } // namespace glcts
378 
379 #endif // _ESEXTCGEOMETRYSHADERINPUT_HPP
380