• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ESEXTCGEOMETRYSHADERPRIMITIVECOUNTER_HPP
2 #define _ESEXTCGEOMETRYSHADERPRIMITIVECOUNTER_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 <string.h>
28 
29 namespace glcts
30 {
31 
32 struct DataPrimitiveIDInCounter
33 {
34 	glw::GLenum m_drawMode;
35 	std::string m_emitVertexCodeForGeometryShader;
36 	glw::GLenum m_feedbackMode;
37 	std::string m_layoutIn;
38 	std::string m_layoutOut;
39 	glw::GLuint m_numberOfVerticesPerOneOutputPrimitive;
40 	glw::GLuint m_numberOfVerticesPerOneInputPrimitive;
41 	glw::GLuint m_numberOfDrawnPrimitives;
42 };
43 
44 /** Implementation of "Group 6" from CTS_EXT_geometry_shader.
45  *   Test Group for "Group 6" tests, storing configuration data and initializing the tests.
46  *   All tests from "Group 6" and children of GeometryShaderPrimitiveCounterTestGroup.
47  */
48 class GeometryShaderPrimitiveCounterTestGroup : public TestCaseGroupBase
49 {
50 public:
51 	/* Public methods */
52 	GeometryShaderPrimitiveCounterTestGroup(Context& context, const ExtParameters& extParams, const char* name,
53 											const char* description);
54 
~GeometryShaderPrimitiveCounterTestGroup()55 	virtual ~GeometryShaderPrimitiveCounterTestGroup()
56 	{
57 	}
58 
59 	virtual void init(void);
60 };
61 
62 /**
63  * 1. Make sure that a built-in geometry shader's input variable
64  *    gl_PrimitiveIDIn increments correctly for all valid <draw call mode,
65  *    input primitive type, output primitive type> tuples.
66  "
67  *    Category: API;
68  *              Functional Test.
69  *
70  *    Let N_VERTICES represent amount of vertices that must be emitted, given
71  *    active geometry shader's output primitive type, to form a single
72  *    primitive that can be passed to rasterization stage
73  *
74  *    Use Transform Feedback functionality to capture gl_PrimitiveIDIn value
75  *    as read in the geometry shader:
76  *
77  *    - The shader should emit:
78  *
79  *      floor(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT / N_VERTICES) / (4 + 1)
80  *
81  *      primitives. It should call EndPrimitive() every N_VERTICES vertices
82  *      emitted.
83  *
84  *    - The draw call should be made for 1024 primitives.
85  *
86  *    Test should fail if the result data for any of the tuples is determined
87  *    to be incorrect.
88  */
89 class GeometryShaderPrimitiveCounter : public TestCaseBase
90 {
91 public:
92 	/* Public methods */
93 	GeometryShaderPrimitiveCounter(Context& context, const ExtParameters& extParams, const char* name,
94 								   const char* description, const DataPrimitiveIDInCounter& testConfiguration);
95 
~GeometryShaderPrimitiveCounter(void)96 	virtual ~GeometryShaderPrimitiveCounter(void)
97 	{
98 	}
99 
100 	virtual void		  deinit(void);
101 	virtual IterateResult iterate(void);
102 
103 protected:
104 	/* Protected methods */
105 	bool checkResult(const glw::GLint* feedbackResult);
106 	void createAndBuildProgramWithFeedback(void);
107 	void drawAndGetFeedback(glw::GLint* feedbackResult);
108 	void prepareBufferObjects();
109 
110 	/* Protected virtual methods */
111 	virtual void drawFunction();
112 
113 	/* Protected members */
114 	DataPrimitiveIDInCounter m_testConfiguration;
115 
116 	glw::GLuint m_nrVaryings;
117 	glw::GLuint m_sizeOfDataArray;
118 	glw::GLuint m_sizeOfFeedbackBuffer;
119 
120 	const glw::GLuint m_n_components;
121 
122 private:
123 	/* Private functions */
124 	std::string GetGeometryShaderCode(const std::string& max_vertices, const std::string& layout_in,
125 									  const std::string& layout_out, const std::string& emit_vertices,
126 									  const std::string& n_iterations);
127 
128 	/* Private variables */
129 	static const char* m_fragment_shader_code;
130 	static const char* m_vertex_shader_code;
131 
132 	glw::GLint m_maxGeometryOutputVertices;
133 
134 	glw::GLuint m_fragment_shader_id;
135 	glw::GLuint m_geometry_shader_id;
136 	glw::GLuint m_vertex_shader_id;
137 	glw::GLuint m_program_id;
138 
139 	glw::GLuint m_tbo;
140 	glw::GLuint m_vao;
141 	glw::GLuint m_vbo;
142 };
143 
144 /** 2. Make sure that restarting a primitive topology with a primitive restart
145  *     index does not affect primitive ID counter, when a element-driven draw
146  *     call is made.
147  *
148  *     Category: API;
149  *               Functional Test.
150  *
151  *     Modify test case 6.1 so that it uses element-sourced data. Insert the
152  *     restart primitive index right after first primitive is rendered but
153  *     before indices for the second one start.
154  */
155 class GeometryShaderPrimitiveCounterRestartingPrimitive : public GeometryShaderPrimitiveCounter
156 {
157 public:
158 	/* Public methods */
159 	GeometryShaderPrimitiveCounterRestartingPrimitive(Context& context, const ExtParameters& extParams,
160 													  const char* name, const char* description,
161 													  const DataPrimitiveIDInCounter& testConfiguration);
162 
~GeometryShaderPrimitiveCounterRestartingPrimitive(void)163 	virtual ~GeometryShaderPrimitiveCounterRestartingPrimitive(void)
164 	{
165 	}
166 
167 	virtual void		  deinit(void);
168 	virtual IterateResult iterate(void);
169 
170 protected:
171 	/* Protected functions */
172 	virtual void drawFunction();
173 	void		 setUpVertexAttributeArrays();
174 
175 private:
176 	/* Private fields */
177 	glw::GLuint m_bo_id;
178 	glw::GLuint m_numberOfRestarts;
179 };
180 
181 /** 3. Make sure that gl_PrimitiveID built-in variable can be read correctly
182  *      from a fragment shader, assuming geometry shader writes to it in
183  *      previous stage.
184  *
185  *      Category: API;
186  *                Functional Test.
187  *
188  *      Vertex shader should output an int variable called vs_vertex_id, to which
189  *      gl_VertexID has been saved.
190  *
191  *      Geometry shader should take points and output a triangle strip. It will
192  *      emit up to 4 vertices. The geometry shader should define an input int
193  *      variable called vs_vertex_id. Let:
194  *
195  *      int column = vs_vertex_id % 64;
196  *      int row = floor(vs_vertex_id / 64);
197  *
198  *      The shader should emit the following vertices:
199  *
200  *      1) (-1.0 + (column+1) / 32.0, -1.0 + (row + 1) / 32.0, 0, 1)
201  *      2) (-1.0 + (column+1) / 32.0, -1.0 + (row)     / 32.0, 0, 1)
202  *      3) (-1.0 + (column)   / 32.0, -1.0 + (row + 1) / 32.0, 0, 1)
203  *      4) (-1.0 + (column)   / 32.0, -1.0 + (row)     / 32.0, 0, 1)
204  *
205  *      Finally, the geometry shader should set gl_PrimitiveID for each of the
206  *      vertices to vs_vertex_id.
207  *
208  *      Fragment shader should set output variable's result value as follows: (*)
209  *
210  *      result[0] =      (gl_PrimitiveID % 64) / 64.0;
211  *      result[1] = floor(gl_PrimitiveID / 64) / 64.0;
212  *      result[2] =       gl_PrimitiveID       / 4096.0;
213  *      result[3] = ((gl_PrimitiveID % 2) == 0) ? 1.0 : 0.0;
214  *
215  *      Using a program object built of these shader, the test should issue
216  *      a draw call for 4096 points. The test is considered to have passed
217  *      successfully if the rendered data consists of 4096 rectangles of edge
218  *      equal to 1/64th of the output resolution, centers of which have values
219  *      as described in (*).
220  *
221  *      Texture object used as color attachment should be at least of 1024x1024
222  *      resolution, in which case quad edge will be 4px long.
223  */
224 class GeometryShaderPrimitiveIDFromFragmentShader : public TestCaseBase
225 {
226 public:
227 	/* Publi methods */
228 	GeometryShaderPrimitiveIDFromFragmentShader(Context& context, const ExtParameters& extParams, const char* name,
229 												const char* description);
230 
~GeometryShaderPrimitiveIDFromFragmentShader(void)231 	virtual ~GeometryShaderPrimitiveIDFromFragmentShader(void)
232 	{
233 	}
234 
235 	void		  deinit(void);
236 	IterateResult iterate(void);
237 
238 private:
239 	/* Private fields */
240 	static const char* m_fragment_shader_code;
241 	static const char* m_geometry_shader_code;
242 	static const char* m_vertex_shader_code;
243 
244 	const glw::GLuint m_n_drawn_vertices;
245 	const glw::GLuint m_squareEdgeSize;
246 	const glw::GLuint m_texture_height;
247 	const glw::GLuint m_texture_n_components;
248 	const glw::GLuint m_texture_n_levels;
249 	const glw::GLuint m_texture_width;
250 
251 	glw::GLuint m_fbo_id;
252 	glw::GLuint m_fragment_shader_id;
253 	glw::GLuint m_geometry_shader_id;
254 	glw::GLuint m_program_id;
255 	glw::GLuint m_texture_id;
256 	glw::GLuint m_vao_id;
257 	glw::GLuint m_vbo_id;
258 	glw::GLuint m_vertex_shader_id;
259 };
260 
261 } // namespace glcts
262 
263 #endif // _ESEXTCGEOMETRYSHADERPRIMITIVECOUNTER_HPP
264