1 #ifndef _ESEXTCGEOMETRYSHADEROUTPUT_HPP
2 #define _ESEXTCGEOMETRYSHADEROUTPUT_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 /** Base class for Geometry Shader Output test implementations. */
31 class GeometryShaderOutput : public TestCaseBase
32 {
33 protected:
34     /* Protected methods */
35     GeometryShaderOutput(Context &context, const ExtParameters &extParams, const char *name, const char *description);
~GeometryShaderOutput()36     virtual ~GeometryShaderOutput()
37     {
38     }
39 
40     /* Protected variables */
41     static const char *const m_fragment_shader_code_white_color;
42     static const char *const m_vertex_shader_code_two_vec4;
43     static const char *const m_vertex_shader_code_vec4_0_0_0_1;
44 };
45 
46 /** Implementation of test case 12.1. Test description follows:
47  *
48  *  It is an error to use two conflicting output primitive type declarations
49  *  in one geometry shader.
50  *
51  *  Category: API;
52  *            Negative Test.
53  *
54  *  Create a program object, for which a boilerplate fragment and vertex
55  *  shaders will be used. A geometry shader should also be attached to the
56  *  program object. The shader should include the following incorrect output
57  *  primitive type declarations:
58  *
59  *  layout(triangle_strip, max_vertices = 60) out;
60  *  layout(points) out;
61  *
62  *  Linking of the program object is expected to fail under this
63  *  configuration.
64  */
65 class GeometryShaderDuplicateOutputLayoutQualifierTest : public GeometryShaderOutput
66 {
67 public:
68     /* Public methods */
69     GeometryShaderDuplicateOutputLayoutQualifierTest(Context &context, const ExtParameters &extParams, const char *name,
70                                                      const char *description);
~GeometryShaderDuplicateOutputLayoutQualifierTest()71     virtual ~GeometryShaderDuplicateOutputLayoutQualifierTest()
72     {
73     }
74 
75     virtual IterateResult iterate(void);
76 
77 protected:
78     /* Protected variables */
79     static const char *const m_geometry_shader_code;
80 };
81 
82 /** Implementation of test case 12.2. Test description follows:
83  *
84  *  It is an error to use two conflicting max_vertices declarations in one
85  *  geometry shader.
86  *
87  *  Category: API;
88  *            Negative Test.
89  *
90  *  Create a program object, for which a boilerplate fragment and vertex
91  *  shaders will be used. A geometry shader should also be attached to the
92  *  program object. The shader should include the following incorrect output
93  *  primitive type declarations:
94  *
95  *  layout(triangle_strip, max_vertices = 60) out;
96  *  layout(max_vertices = 20) out;
97  *
98  *  Linking of the program object is expected to fail under this
99  *  configuration.
100  **/
101 class GeometryShaderDuplicateMaxVerticesLayoutQualifierTest : public GeometryShaderOutput
102 {
103 public:
104     /* Public methods */
105     GeometryShaderDuplicateMaxVerticesLayoutQualifierTest(Context &context, const ExtParameters &extParams,
106                                                           const char *name, const char *description);
~GeometryShaderDuplicateMaxVerticesLayoutQualifierTest()107     virtual ~GeometryShaderDuplicateMaxVerticesLayoutQualifierTest()
108     {
109     }
110 
111     virtual IterateResult iterate(void);
112 
113 protected:
114     /* Protected variables */
115     static const char *const m_geometry_shader_code;
116 };
117 
118 /** Base class for tests 12.3, 12.4 and 12.5.
119      *
120      *  Test class have to:
121          - provide geometry shader code via constructor parameter,
122          - override method verifyResult.
123      **/
124 class GeometryShaderOutputRenderingBase : public GeometryShaderOutput
125 {
126 public:
127     virtual void deinit(void);
128     virtual IterateResult iterate(void);
129     virtual bool verifyResult(const unsigned char *result_image, unsigned int width, unsigned int height,
130                               unsigned int pixel_size) const = 0;
131 
132 protected:
133     /* Protected methods */
134     GeometryShaderOutputRenderingBase(Context &context, const ExtParameters &extParams, const char *name,
135                                       const char *description, const char *geometry_shader_code);
~GeometryShaderOutputRenderingBase()136     virtual ~GeometryShaderOutputRenderingBase()
137     {
138     }
139 
140     void initTest(void);
141 
142 private:
143     /* Private variables */
144     const char *m_geometry_shader_code;
145 
146     glw::GLuint m_program_object_id;
147     glw::GLuint m_vertex_shader_id;
148     glw::GLuint m_fragment_shader_id;
149     glw::GLuint m_geometry_shader_id;
150 
151     glw::GLuint m_vao_id;
152     glw::GLuint m_fbo_id;
153     glw::GLuint m_color_tex_id;
154 };
155 
156 /** Implementation of test case 12.3. Test description follows:
157  *
158  *  Make sure that EndPrimitive() does not emit a vertex.
159  *
160  *  Category: API;
161  *            Functional Test.
162  *
163  *  Consider a FBO with a single 16x16 2D texture object attached to color
164  *  attachment 0 and made active.
165  *
166  *  The texture object should be filled with (0, 0, 0, 0).
167  *
168  *  A boilerplate vertex shader should be assumed for the test case.
169  *
170  *  Consider a geometry shader that takes a point as input and outputs
171  *  a triangle strip (a max of 3 vertices will be emitted). The shader
172  *  should:
173  *
174  *  - Emit a vertex at   (-1, -1, 0, 1).
175  *  - Emit a vertex at   (-1,  1, 0, 1).
176  *  - Set gl_Position to ( 1,  1, 0, 1).
177  *  - Do a EndPrimitive() call.
178  *
179  *  A fragment shader should set the only output vec4 variable to
180  *  (1, 1, 1, 1).
181  *
182  *  A program object consisting of all three shaders should be created and
183  *  linked.
184  *
185  *  A single point draw call should be issued.
186  *
187  *  At this point the test should verify that the texture object has not been
188  *  modified, that is: all texels are set to (0, 0, 0, 0).
189  **/
190 class GeometryShaderIfVertexEmitIsDoneAtEndTest : public GeometryShaderOutputRenderingBase
191 {
192 public:
193     /* Public methods */
194     GeometryShaderIfVertexEmitIsDoneAtEndTest(Context &context, const ExtParameters &extParams, const char *name,
195                                               const char *description);
~GeometryShaderIfVertexEmitIsDoneAtEndTest()196     virtual ~GeometryShaderIfVertexEmitIsDoneAtEndTest()
197     {
198     }
199 
200     virtual bool verifyResult(const unsigned char *result_image, unsigned int width, unsigned int height,
201                               unsigned int pixel_size) const;
202 
203 protected:
204     /* Protected variables */
205     static const char *const m_geometry_shader_code;
206 };
207 
208 /** Implementation of test case 12.4. Test description follows:
209  *
210  *  Make sure that a geometry shader completes current output primitive upon
211  *  termination.
212  *
213  *  Category: API;
214  *            Functional Test.
215  *
216  *  Modify test case 12.3 by:
217  *
218  *  - Removing EndPrimitive() call the geometry shader should do at the end.
219  *  - Changing the test check condition: test now succeeds if texels at
220  *    bottom-left, top-left and top-right corners are set to
221  *    (255, 255, 255, 255) and bottom-right corner is set to (0, 0, 0, 0),
222  *    assuming glReadPixels() was called with GL_RGBA format and
223  *    GL_UNSIGNED_BYTE type.
224  **/
225 class GeometryShaderMissingEndPrimitiveCallTest : public GeometryShaderOutputRenderingBase
226 {
227 public:
228     /* Public methods */
229     GeometryShaderMissingEndPrimitiveCallTest(Context &context, const ExtParameters &extParams, const char *name,
230                                               const char *description);
~GeometryShaderMissingEndPrimitiveCallTest()231     virtual ~GeometryShaderMissingEndPrimitiveCallTest()
232     {
233     }
234 
235     virtual bool verifyResult(const unsigned char *result_image, unsigned int width, unsigned int height,
236                               unsigned int pixel_size) const;
237 
238 protected:
239     /* Protected variables */
240     static const char *const m_geometry_shader_code;
241 };
242 
243 /** Implementation of test case 12.5. Test description follows:
244  *
245  *  Make sure that it is not necessary to do an EndPrimitive() call if the
246  *  geometry shader only writes a single primitive.
247  *
248  *  Category: API;
249  *            Functional Test.
250  *
251  *  Modify test case 12.3 by:
252  *
253  *  - Changing the logic in geometry shader to only set gl_Position to
254  *    (-1, -1, 0, 1).
255  *  - Changing input and output primitive types in a geometry shader to
256  *    points.
257  *  - Changing max_vertices to 1.
258  *  - Pixel size should also be set to 2 prior to issuing the draw call.
259  *  - Changing the test check condition: test now succeeds if texel at
260  *    bottom-left corner is set to (255, 255, 255, 255) and remaining corners
261  *    are set to (0, 0, 0, 0), assuming glReadPixels() was called with
262  *    GL_RGBA format and GL_UNSIGNED_BYTE type.
263  **/
264 class GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest : public GeometryShaderOutputRenderingBase
265 {
266 public:
267     /* Public methods */
268     GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest(Context &context, const ExtParameters &extParams,
269                                                                 const char *name, const char *description);
~GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest()270     virtual ~GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest()
271     {
272     }
273 
274     virtual IterateResult iterate(void);
275 
276     virtual bool verifyResult(const unsigned char *result_image, unsigned int width, unsigned int height,
277                               unsigned int pixel_size) const;
278 
279 protected:
280     /* Protected variables */
281     static const char *const m_geometry_shader_code;
282 };
283 } // namespace glcts
284 
285 #endif // _ESEXTCGEOMETRYSHADEROUTPUT_HPP
286