• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ESEXTCGEOMETRYSHADERLIMITS_HPP
2 #define _ESEXTCGEOMETRYSHADERLIMITS_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 /*!
27  * \file esextcGeometryShaderLimits.hpp
28  * \brief Geometry Shader Limits (Test Group 16)
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "../esextcTestCaseBase.hpp"
32 
33 #include <vector>
34 
35 namespace glcts
36 {
37 /** Parent class for geometry shader Test Group 16 tests
38  *  based on fetching result via transfrom feedback.
39  **/
40 class GeometryShaderLimitsTransformFeedbackBase : public TestCaseBase
41 {
42 public:
43 	/* Public methods */
44 	virtual void		  deinit(void);
45 	virtual IterateResult iterate(void);
46 
47 protected:
48 	/* Protected methods */
49 	GeometryShaderLimitsTransformFeedbackBase(Context& context, const ExtParameters& extParams, const char* name,
50 											  const char* description);
51 
~GeometryShaderLimitsTransformFeedbackBase()52 	virtual ~GeometryShaderLimitsTransformFeedbackBase()
53 	{
54 	}
55 
56 	void initTest(void);
57 
58 	/* Methods to be overriden by inheriting test cases */
59 	virtual void clean() = 0;
60 
61 	virtual void getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names,
62 									 glw::GLuint&				out_n_captured_varyings) = 0;
63 
64 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
65 								glw::GLuint&			   out_n_fragment_shader_parts,
66 								const glw::GLchar* const*& out_geometry_shader_parts,
67 								glw::GLuint&			   out_n_geometry_shader_parts,
68 								const glw::GLchar* const*& out_vertex_shader_parts,
69 								glw::GLuint&			   out_n_vertex_shader_parts) = 0;
70 
71 	virtual void getTransformFeedbackBufferSize(glw::GLuint& out_buffer_size) = 0;
72 	virtual void prepareProgramInput()										  = 0;
73 	virtual bool verifyResult(const void* data)								  = 0;
74 
75 	/* Protected fields */
76 	/* Program and shader ids */
77 	glw::GLuint m_fragment_shader_id;
78 	glw::GLuint m_geometry_shader_id;
79 	glw::GLuint m_program_object_id;
80 	glw::GLuint m_vertex_shader_id;
81 
82 	/* Buffer object used in transform feedback */
83 	glw::GLuint m_buffer_object_id;
84 
85 	/* Vertex array object */
86 	glw::GLuint m_vertex_array_object_id;
87 
88 private:
89 	/* Private fields */
90 	/* Shaders' code */
91 	const glw::GLchar* const* m_fragment_shader_parts;
92 	const glw::GLchar* const* m_geometry_shader_parts;
93 	const glw::GLchar* const* m_vertex_shader_parts;
94 
95 	glw::GLuint m_n_fragment_shader_parts;
96 	glw::GLuint m_n_geometry_shader_parts;
97 	glw::GLuint m_n_vertex_shader_parts;
98 
99 	/* Names of varyings */
100 	const glw::GLchar* const* m_captured_varyings_names;
101 	glw::GLuint				  m_n_captured_varyings;
102 
103 	/* Size of buffer used by transform feedback */
104 	glw::GLuint m_buffer_size;
105 };
106 
107 /** Parent class for geometry shader Test Group 16 tests
108  *  based on fetching result via rendering to texture.
109  **/
110 class GeometryShaderLimitsRenderingBase : public TestCaseBase
111 {
112 public:
113 	/* Public methods */
114 	virtual void		  deinit(void);
115 	virtual IterateResult iterate(void);
116 
117 protected:
118 	/* Protected methods */
119 	GeometryShaderLimitsRenderingBase(Context& context, const ExtParameters& extParams, const char* name,
120 									  const char* description);
121 
~GeometryShaderLimitsRenderingBase()122 	virtual ~GeometryShaderLimitsRenderingBase()
123 	{
124 	}
125 
126 	void initTest(void);
127 
128 	/* Methods to be overriden by child test cases */
129 	virtual void clean() = 0;
130 
131 	virtual void getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices) = 0;
132 
133 	virtual void getFramebufferDetails(glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format,
134 									   glw::GLenum& out_texture_read_type, glw::GLuint& out_texture_width,
135 									   glw::GLuint& out_texture_height, glw::GLuint& out_texture_pixel_size) = 0;
136 
137 	virtual void getRequiredPointSize(glw::GLfloat& out_point_size) = 0;
138 
139 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
140 								glw::GLuint&			   out_n_fragment_shader_parts,
141 								const glw::GLchar* const*& out_geometry_shader_parts,
142 								glw::GLuint&			   out_n_geometry_shader_parts,
143 								const glw::GLchar* const*& out_vertex_shader_parts,
144 								glw::GLuint&			   out_n_vertex_shader_parts) = 0;
145 
146 	virtual void prepareProgramInput()			= 0;
147 	virtual bool verifyResult(const void* data) = 0;
148 
149 	/* Protected fields */
150 	/* Program and shader ids */
151 	glw::GLuint m_fragment_shader_id;
152 	glw::GLuint m_geometry_shader_id;
153 	glw::GLuint m_program_object_id;
154 	glw::GLuint m_vertex_shader_id;
155 
156 	/* Framebuffer object id */
157 	glw::GLuint m_framebuffer_object_id;
158 	glw::GLuint m_color_texture_id;
159 
160 	/* Vertex array object */
161 	glw::GLuint m_vertex_array_object_id;
162 
163 private:
164 	/* Private fields */
165 	/* Shaders' code */
166 	const glw::GLchar* const* m_fragment_shader_parts;
167 	const glw::GLchar* const* m_geometry_shader_parts;
168 	const glw::GLchar* const* m_vertex_shader_parts;
169 
170 	glw::GLuint m_n_fragment_shader_parts;
171 	glw::GLuint m_n_geometry_shader_parts;
172 	glw::GLuint m_n_vertex_shader_parts;
173 
174 	/* Framebuffer dimensions */
175 	glw::GLenum m_texture_format;
176 	glw::GLuint m_texture_height;
177 	glw::GLuint m_texture_pixel_size;
178 	glw::GLenum m_texture_read_format;
179 	glw::GLenum m_texture_read_type;
180 	glw::GLuint m_texture_width;
181 };
182 
183 /** Implementation of test case 16.1. Test description follows:
184  *
185  *  Make sure it is possible to use as many uniform components as defined
186  *  by GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT
187  *
188  *  Category: API;
189  *            Functional Test.
190  *
191  *  1. Create a fragment, geometry and vertex shader objects:
192  *
193  *  - Vertex shader code can be boilerplate;
194  *  - Geometry shader code should define
195  *    floor(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT / 4) uniform ivec4
196  *    variables. It should take points as input and output, a maximum of
197  *    1 vertex will be written by the shader. In main(), the shader should
198  *    set output int variable named result to a sum of all the vectors'
199  *    components and emit a vertex.
200  *  - Fragment shader code can be boilerplate.
201  *
202  *  2. The program object consisting of these shader objects is expected to
203  *  link successfully.
204  *
205  *  3. Configure the uniforms to use subsequently increasing values, starting
206  *  from 1 for R component of first vector, 2 for G component of that vector,
207  *  5 for first component of second vector, and so on.
208  *
209  *  4. Configure transform feedback object to capture output from result.
210  *  Draw a single point. The test succeeds if first component of the result
211  *  vector contains a valid value (bearing potentially minor precision issues
212  *  in mind)
213  **/
214 class GeometryShaderMaxUniformComponentsTest : public GeometryShaderLimitsTransformFeedbackBase
215 {
216 public:
217 	/* Public methods */
218 	GeometryShaderMaxUniformComponentsTest(Context& context, const ExtParameters& extParams, const char* name,
219 										   const char* description);
220 
~GeometryShaderMaxUniformComponentsTest()221 	virtual ~GeometryShaderMaxUniformComponentsTest()
222 	{
223 	}
224 
225 protected:
226 	/* Overriden from GeometryShaderLimitsTransformFeedbackBase */
227 	virtual void clean();
228 
229 	virtual void getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names,
230 									 glw::GLuint&				out_n_captured_varyings);
231 
232 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
233 								glw::GLuint&			   out_n_fragment_shader_parts,
234 								const glw::GLchar* const*& out_geometry_shader_parts,
235 								glw::GLuint&			   out_n_geometry_shader_parts,
236 								const glw::GLchar* const*& out_vertex_shader_parts,
237 								glw::GLuint&			   out_n_vertex_shader_parts);
238 
239 	virtual void getTransformFeedbackBufferSize(glw::GLuint& out_buffer_size);
240 	virtual void prepareProgramInput();
241 	virtual bool verifyResult(const void* data);
242 
243 private:
244 	/* Private fields */
245 	/* Shaders' code */
246 	static const glw::GLchar* const m_fragment_shader_code;
247 	static const glw::GLchar* const m_geometry_shader_code_preamble;
248 	static const glw::GLchar* const m_geometry_shader_code_number_of_uniforms;
249 	static const glw::GLchar* const m_geometry_shader_code_body;
250 	static const glw::GLchar* const m_vertex_shader_code;
251 
252 	const glw::GLchar* m_geometry_shader_parts[4];
253 
254 	/* String used to store number of uniform vectors */
255 	std::string m_max_uniform_vectors_string;
256 
257 	/* Varying names */
258 	static const glw::GLchar* const m_captured_varyings_names;
259 
260 	/* Buffer size */
261 	static const glw::GLuint m_buffer_size;
262 
263 	/* Max uniform components and vectors */
264 	glw::GLint m_max_uniform_components;
265 	glw::GLint m_max_uniform_vectors;
266 
267 	/* Uniform location */
268 	glw::GLint m_uniform_location;
269 
270 	/* Uniform data */
271 	std::vector<glw::GLint> m_uniform_data;
272 };
273 
274 /** Implementation of test case 16.2. Test description follows:
275  *
276  *  Make sure it is possible to use as many uniform blocks as defined by
277  *  GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT
278  *
279  *  Category: API;
280  *            Functional Test.
281  *
282  *  Slightly modify test case 16.1 to use a similar idea to test if the
283  *  value reported for the property by the implementation is reliable:
284  *
285  *  - Test case 16.1's ivec4s take form of as many uniform blocks as needed,
286  *    each hosting a single int.
287  *  - The result value to be calculated in the geometry shader is a sum of
288  *    all ints, stored in output int result variable.
289  **/
290 class GeometryShaderMaxUniformBlocksTest : public GeometryShaderLimitsTransformFeedbackBase
291 {
292 public:
293 	/* Public methods */
294 	GeometryShaderMaxUniformBlocksTest(Context& context, const ExtParameters& extParams, const char* name,
295 									   const char* description);
296 
~GeometryShaderMaxUniformBlocksTest()297 	virtual ~GeometryShaderMaxUniformBlocksTest()
298 	{
299 	}
300 
301 protected:
302 	/* Overriden from GeometryShaderLimitsTransformFeedbackBase */
303 	virtual void clean();
304 
305 	virtual void getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names,
306 									 glw::GLuint&				out_n_captured_varyings);
307 
308 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
309 								glw::GLuint&			   out_n_fragment_shader_parts,
310 								const glw::GLchar* const*& out_geometry_shader_parts,
311 								glw::GLuint&			   out_n_geometry_shader_parts,
312 								const glw::GLchar* const*& out_vertex_shader_parts,
313 								glw::GLuint&			   out_n_vertex_shader_parts);
314 
315 	virtual void getTransformFeedbackBufferSize(glw::GLuint& out_buffer_size);
316 	virtual void prepareProgramInput();
317 	virtual bool verifyResult(const void* data);
318 
319 private:
320 	/* Private type */
321 	struct _uniform_block
322 	{
323 		glw::GLuint buffer_object_id;
324 		glw::GLint  data;
325 	};
326 
327 	/* Private fields */
328 	/* Shaders' code */
329 	static const glw::GLchar* const m_fragment_shader_code;
330 	static const glw::GLchar* const m_geometry_shader_code_preamble;
331 	static const glw::GLchar* const m_geometry_shader_code_number_of_uniforms;
332 	static const glw::GLchar* const m_geometry_shader_code_body_str;
333 	static const glw::GLchar* const m_geometry_shader_code_body_end;
334 	static const glw::GLchar* const m_vertex_shader_code;
335 
336 	const glw::GLchar* m_geometry_shader_parts[6];
337 
338 	/* String used to store uniform blocks accesses */
339 	std::string m_uniform_block_access_string;
340 
341 	/* String used to store number of uniform blocks */
342 	std::string m_max_uniform_blocks_string;
343 
344 	/* Varying names */
345 	static const glw::GLchar* const m_captured_varyings_names;
346 
347 	/* Buffer size */
348 	static const glw::GLuint m_buffer_size;
349 
350 	/* Max uniform blocks */
351 	glw::GLint m_max_uniform_blocks;
352 
353 	/* Uniform blocks data */
354 	std::vector<_uniform_block> m_uniform_blocks;
355 };
356 
357 /** Implementation of test case 16.3. Test description follows:
358  *
359  *  Make sure it is possible to use as many input components as defined by
360  *  GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT
361  *
362  *  Category: API.
363  *
364  *  Create a program object, attach a fragment, geometry and a vertex shader to it:
365  *
366  *  - Fragment shader can be boilerplate;
367  *  - Vertex shader should define exactly
368  *    (GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT / 4) ivec4 output variables.
369  *    Each of the variables should be assigned a vector value of
370  *    (n, n+1, n+2, n+3) where n corresponds to "index" of the variable,
371  *    assuming the very first output variable has an "index" of 1.
372  *  - Geometry shader should define exactly
373  *    (GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT / 4) vec4 input variables. It
374  *    should accept input point geometry and output a maximum of 1 point.
375  *    It should sum up all components read from input variables and store them
376  *    in output int variable called result..
377  *
378  *  The test should then configure the program object to capture values of
379  *  "result" variable using transform feedback and link the program object.
380  *
381  *  The test should now generate and bind a vertex array object, and then
382  *  draw a single point. Test succeeds if the value stored in a buffer object
383  *  configured for transform feedback storage is valid.
384  **/
385 class GeometryShaderMaxInputComponentsTest : public GeometryShaderLimitsTransformFeedbackBase
386 {
387 public:
388 	/* Public methods */
389 	GeometryShaderMaxInputComponentsTest(Context& context, const ExtParameters& extParams, const char* name,
390 										 const char* description);
391 
~GeometryShaderMaxInputComponentsTest()392 	virtual ~GeometryShaderMaxInputComponentsTest()
393 	{
394 	}
395 
396 protected:
397 	/* Overriden from GeometryShaderLimitsTransformFeedbackBase */
398 	virtual void clean();
399 
400 	virtual void getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names,
401 									 glw::GLuint&				out_n_captured_varyings);
402 
403 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
404 								glw::GLuint&			   out_n_fragment_shader_parts,
405 								const glw::GLchar* const*& out_geometry_shader_parts,
406 								glw::GLuint&			   out_n_geometry_shader_parts,
407 								const glw::GLchar* const*& out_vertex_shader_parts,
408 								glw::GLuint&			   out_n_vertex_shader_parts);
409 
410 	virtual void getTransformFeedbackBufferSize(glw::GLuint& out_buffer_size);
411 	virtual void prepareProgramInput();
412 	virtual bool verifyResult(const void* data);
413 
414 private:
415 	/* Private fields */
416 	/* Shaders' code */
417 	static const glw::GLchar* const m_fragment_shader_code;
418 	static const glw::GLchar* const m_geometry_shader_code_preamble;
419 	static const glw::GLchar* const m_geometry_shader_code_number_of_uniforms;
420 	static const glw::GLchar* const m_geometry_shader_code_body;
421 	static const glw::GLchar* const m_vertex_shader_code_preamble;
422 	static const glw::GLchar* const m_vertex_shader_code_number_of_uniforms;
423 	static const glw::GLchar* const m_vertex_shader_code_body;
424 
425 	const glw::GLchar* m_geometry_shader_parts[4];
426 	const glw::GLchar* m_vertex_shader_parts[4];
427 
428 	/* Max input components and vectors */
429 	glw::GLint m_max_geometry_input_components;
430 	glw::GLint m_max_geometry_input_vectors;
431 
432 	/* String used to store number of geometry input vectors */
433 	std::string m_max_geometry_input_vectors_string;
434 
435 	/* Varying names */
436 	static const glw::GLchar* const m_captured_varyings_names;
437 
438 	/* Buffer size */
439 	static const glw::GLuint m_buffer_size;
440 };
441 
442 /** Implementation of test case 16.4. Test description follows:
443  *
444  *  Make sure it is possible to use as many total output components as
445  *  defined by GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT.
446  *
447  *  Category: API.
448  *
449  *  Let n_points be equal to:
450  *
451  *  (GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT / GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT)
452  *
453  *  Create a fragment, geometry and vertex shader objects:
454  *
455  *  - Vertex shader code can be boilerplate;
456  *  - Geometry shader code should define:
457  *
458  *             floor(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT / 4)
459  *
460  *   output ivec4 variables. It should take points as input and output,
461  *   a maximum of n_points vertices will be written. In main(), for each
462  *   vertex, the shader should set gl_Position to:
463  *
464  *         (-1 + (2 * vertex id + 1) / (2 * max vertices) * 2, 0, 0, 1)
465  *
466  *   where (vertex id) corresponds to index of about-to-be-emitted vertices,
467  *   assuming the indexing starts from 0.
468  *   Each vertex should store subsequently increasing, unique values to
469  *   components of the output variables.
470  *   Geometry shader should emit as many vertices as specified. For each
471  *   output point, point size should be set to 2.
472  *  - Fragment shader code should take all aforementioned varyings as input
473  *   variables, read them, and store result int fragment as sum of all
474  *   components for all vectors passed from the geometry shader.
475  *
476  *  For rendering, the test should use a framebuffer object, to which
477  *  a GL_R32I-based 2D texture object of resolution:
478  *
479  *                              (2*n_points, 2)
480  *
481  *  has been attached to color attachment 0.
482  *
483  *  The test should link the program (no linking error should be reported)
484  *  and then activate it. Having bound a vertex array object, it should then
485  *  draw n_points points.
486  *
487  *  The test passes, if the texture attached to color attachment 0 consists
488  *  of 2x2 quads filled with the same value, that can be considered valid in
489  *  light of the description above.
490  *  The program object consisting of these shader objects is expected to link
491  *  successfully.
492  **/
493 class GeometryShaderMaxOutputComponentsTest : public GeometryShaderLimitsRenderingBase
494 {
495 public:
496 	/* Public methods */
497 	GeometryShaderMaxOutputComponentsTest(Context& context, const ExtParameters& extParams, const char* name,
498 										  const char* description);
499 
~GeometryShaderMaxOutputComponentsTest()500 	virtual ~GeometryShaderMaxOutputComponentsTest()
501 	{
502 	}
503 
504 protected:
505 	/* Methods overriden from GeometryShaderLimitsRenderingBase */
506 	virtual void clean();
507 
508 	virtual void getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices);
509 
510 	virtual void getFramebufferDetails(glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format,
511 									   glw::GLenum& out_texture_read_type, glw::GLuint& out_texture_width,
512 									   glw::GLuint& out_texture_height, glw::GLuint& out_texture_pixel_size);
513 
514 	virtual void getRequiredPointSize(glw::GLfloat& out_point_size);
515 
516 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
517 								glw::GLuint&			   out_n_fragment_shader_parts,
518 								const glw::GLchar* const*& out_geometry_shader_parts,
519 								glw::GLuint&			   out_n_geometry_shader_parts,
520 								const glw::GLchar* const*& out_vertex_shader_parts,
521 								glw::GLuint&			   out_n_vertex_shader_parts);
522 
523 	virtual void prepareProgramInput();
524 	virtual bool verifyResult(const void* data);
525 
526 private:
527 	/* Private methods */
528 	void prepareFragmentShader(std::string& out_shader_code) const;
529 	void prepareGeometryShader(std::string& out_shader_code) const;
530 
531 	/* Private fields */
532 	/* Shaders' code */
533 	static const glw::GLchar* const m_common_shader_code_gs_fs_out;
534 	static const glw::GLchar* const m_common_shader_code_number_of_points;
535 	static const glw::GLchar* const m_common_shader_code_gs_fs_out_definitions;
536 	static const glw::GLchar* const m_fragment_shader_code_preamble;
537 	static const glw::GLchar* const m_fragment_shader_code_flat_in_ivec4;
538 	static const glw::GLchar* const m_fragment_shader_code_sum;
539 	static const glw::GLchar* const m_fragment_shader_code_body_begin;
540 	static const glw::GLchar* const m_fragment_shader_code_body_end;
541 	static const glw::GLchar* const m_geometry_shader_code_preamble;
542 	static const glw::GLchar* const m_geometry_shader_code_layout;
543 	static const glw::GLchar* const m_geometry_shader_code_flat_out_ivec4;
544 	static const glw::GLchar* const m_geometry_shader_code_assignment;
545 	static const glw::GLchar* const m_geometry_shader_code_body_begin;
546 	static const glw::GLchar* const m_geometry_shader_code_body_end;
547 	static const glw::GLchar* const m_vertex_shader_code;
548 
549 	/* Storage for prepared fragment and geometry shader */
550 	std::string		   m_fragment_shader_code;
551 	const glw::GLchar* m_fragment_shader_code_c_str;
552 	std::string		   m_geometry_shader_code;
553 	const glw::GLchar* m_geometry_shader_code_c_str;
554 
555 	/* Framebuffer dimensions */
556 	glw::GLuint				 m_texture_width;
557 	static const glw::GLuint m_texture_height;
558 	static const glw::GLuint m_texture_pixel_size;
559 	static const glw::GLuint m_point_size;
560 
561 	/* Max number of output components */
562 	glw::GLint m_max_output_components;
563 	glw::GLint m_max_output_vectors;
564 	glw::GLint m_max_total_output_components;
565 	glw::GLint m_n_available_vectors;
566 	glw::GLint m_n_output_points;
567 };
568 
569 /** Implementation of test case 16.5. Test description follows:
570  *
571  *  Make sure it possible to request as many output vertices as report for
572  *  GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT. Requesting support for larger amount
573  *  of output vertices should cause the linking process to fail.
574  *
575  *  Category: API;
576  *           Negative Test.
577  *
578  *  Create two program objects and one boilerplate fragment & one boilerplate
579  *  vertex shader objects.
580  *  Also create two boilerplate geometry shader objects where:
581  *
582  *  a) The first geometry shader object can output up to
583  *    GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT vertices.
584  *  b) The other geometry shader object can output up to
585  *    (GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT+1) vertices.
586  *
587  *  1) Program object A should be attached fragment and vertex shader
588  *    objects, as well as geometry shader A. This program object should
589  *    link successfully.
590  *  2) Program object B should be attached fragment and vertex shader objects,
591  *    as well as geometry shader B. This program object should fail to link.
592  **/
593 class GeometryShaderMaxOutputVerticesTest : public TestCaseBase
594 {
595 public:
596 	/* Public methods */
597 	GeometryShaderMaxOutputVerticesTest(Context& context, const ExtParameters& extParams, const char* name,
598 										const char* description);
599 
~GeometryShaderMaxOutputVerticesTest()600 	virtual ~GeometryShaderMaxOutputVerticesTest()
601 	{
602 	}
603 
604 	virtual IterateResult iterate(void);
605 
606 private:
607 	/* Private fields */
608 	/* Shaders' code */
609 	static const glw::GLchar* const m_fragment_shader_code;
610 	static const glw::GLchar* const m_geometry_shader_code_preamble;
611 	static const glw::GLchar* const m_geometry_shader_code_body;
612 	static const glw::GLchar* const m_vertex_shader_code;
613 };
614 
615 /** Implementation of test case 16.6. Test description follows:
616  *
617  *  Make sure it is possible to use as many output components as defined by
618  *  GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT
619  *
620  *  Category: API.
621  *
622  *  Modify test case 16.4, so that:
623  *
624  *  * n_points is always 1;
625  **/
626 class GeometryShaderMaxOutputComponentsSinglePointTest : public GeometryShaderLimitsRenderingBase
627 {
628 public:
629 	/* Public methods */
630 	GeometryShaderMaxOutputComponentsSinglePointTest(Context& context, const ExtParameters& extParams, const char* name,
631 													 const char* description);
632 
~GeometryShaderMaxOutputComponentsSinglePointTest()633 	virtual ~GeometryShaderMaxOutputComponentsSinglePointTest()
634 	{
635 	}
636 
637 protected:
638 	/* Methods overriden from GeometryShaderLimitsRenderingBase */
639 	virtual void clean();
640 
641 	virtual void getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices);
642 
643 	virtual void getFramebufferDetails(glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format,
644 									   glw::GLenum& out_texture_read_type, glw::GLuint& out_texture_width,
645 									   glw::GLuint& out_texture_height, glw::GLuint& out_texture_pixel_size);
646 
647 	virtual void getRequiredPointSize(glw::GLfloat& out_point_size);
648 
649 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
650 								glw::GLuint&			   out_n_fragment_shader_parts,
651 								const glw::GLchar* const*& out_geometry_shader_parts,
652 								glw::GLuint&			   out_n_geometry_shader_parts,
653 								const glw::GLchar* const*& out_vertex_shader_parts,
654 								glw::GLuint&			   out_n_vertex_shader_parts);
655 
656 	virtual void prepareProgramInput();
657 	virtual bool verifyResult(const void* data);
658 
659 private:
660 	/* Private methods */
661 	void prepareFragmentShader(std::string& out_shader_code) const;
662 	void prepareGeometryShader(std::string& out_shader_code) const;
663 
664 	/* Private fields */
665 	/* Shaders' code */
666 	static const glw::GLchar* const m_common_shader_code_gs_fs_out;
667 	static const glw::GLchar* const m_common_shader_code_gs_fs_out_definitions;
668 	static const glw::GLchar* const m_fragment_shader_code_preamble;
669 	static const glw::GLchar* const m_fragment_shader_code_flat_in_ivec4;
670 	static const glw::GLchar* const m_fragment_shader_code_sum;
671 	static const glw::GLchar* const m_fragment_shader_code_body_begin;
672 	static const glw::GLchar* const m_fragment_shader_code_body_end;
673 	static const glw::GLchar* const m_geometry_shader_code_preamble;
674 	static const glw::GLchar* const m_geometry_shader_code_flat_out_ivec4;
675 	static const glw::GLchar* const m_geometry_shader_code_assignment;
676 	static const glw::GLchar* const m_geometry_shader_code_body_begin;
677 	static const glw::GLchar* const m_geometry_shader_code_body_end;
678 	static const glw::GLchar* const m_vertex_shader_code;
679 
680 	/* Storage for prepared fragment and geometry shader */
681 	std::string m_fragment_shader_code;
682 	std::string m_geometry_shader_code;
683 
684 	const glw::GLchar* m_fragment_shader_code_c_str;
685 	const glw::GLchar* m_geometry_shader_code_c_str;
686 
687 	/* Framebuffer dimensions */
688 	static const glw::GLuint m_texture_width;
689 	static const glw::GLuint m_texture_height;
690 	static const glw::GLuint m_texture_pixel_size;
691 	static const glw::GLuint m_point_size;
692 
693 	/* Max number of output components */
694 	glw::GLint m_max_output_components;
695 	glw::GLint m_max_output_vectors;
696 	glw::GLint m_n_available_vectors;
697 };
698 
699 /** Implementation of test case 16.7. Test description follows:
700  *
701  *  Make sure that it is possible to access as many texture image units from
702  *  a geometry shader as reported by GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT
703  *
704  *  Category: API;
705  *            Functional Test.
706  *
707  *  Create as many texture objects as reported by
708  *  GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT. Each texture should be made an
709  *  immutable GL_R32I 2D texture, have 1x1 resolution and be filled with
710  *  subsequently increasing intensities (starting from 1, delta: 2). Let's
711  *  name these textures "source textures" for the purpose of this test case.
712  *
713  *  Create a program object and a fragment/geometry/vertex shader object.
714  *  Behavior of the shaders should be as follows:
715  *
716  *  1) Vertex shader should take gl_VertexID and calculate an unique 2D
717  *  location, that will later be used to render a 2x2 quad. The calculations
718  *  should take quad size into account, note the quads must not overlap. The
719  *  result location should be passed to geometry shader by storing it in an
720  *  output variable. The shader should also store the vertex id in a
721  *  flat-interpolated int output variable called vertex_id.
722  *
723  *  2) Geometry shader should accept points as input types and should emit
724  *  triangle strips with a maximum of 4 output vertices. For each output
725  *  geometry's vertex, two values should be written:
726  *
727  *  * gl_Position obviously;
728  *  * color (stored as flat-interpolated integer);
729  *
730  *  The shader should define as many 2D samplers as reported for the tested
731  *  property. In geometry shader's entry-point, the aforementioned 2D
732  *  location should be used to calculate vertices of a quad the shader will
733  *  emit (built using a triangle strip). Geometry shader should also write
734  *  a result of the following computation to an output color variable:
735  *
736  *  sum(i=0..n_samplers)( (vertex_id == i) * (result of sampling 2D texture
737  *  at (0,0) using a sampler bound to texture unit i) );
738  *
739  *  3) Fragment shader should take the color as passed by geometry shader
740  *  and write it to output result variable.
741  *
742  *  These shader objects should then be compiled, attached to the program
743  *  object. The program object should be linked. Each sampler uniform should
744  *  be assigned a consecutive texture unit index, starting from 0.
745  *
746  *  A framebuffer object should then be created, as well as a 2D GL_R32I
747  *  texture of resolution:
748  *
749  *            (GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT*2, 2)
750  *
751  *  The texture should be attached to the FBO's color attachment.
752  *
753  *  A vertex array object should be created and bound.
754  *
755  *  "Source textures" are next bound to corresponding texture units, and the
756  *  FBO should be made a draw framebuffer. The program object should be made
757  *  current and exactly GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT points should
758  *  be drawn.
759  *
760  *  Next, bind the FBO to GL_READ_FRAMEBUFFER target, read the data, and make
761  *  sure that consequent 2x2 quads are of expected intensities (epsilon to
762  *  consider: +-1).
763  **/
764 class GeometryShaderMaxTextureUnitsTest : public GeometryShaderLimitsRenderingBase
765 {
766 public:
767 	/* Public methods */
768 	GeometryShaderMaxTextureUnitsTest(Context& context, const ExtParameters& extParams, const char* name,
769 									  const char* description);
770 
~GeometryShaderMaxTextureUnitsTest()771 	virtual ~GeometryShaderMaxTextureUnitsTest()
772 	{
773 	}
774 
775 protected:
776 	/* Methods overriden from GeometryShaderLimitsRenderingBase */
777 	virtual void clean();
778 
779 	virtual void getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices);
780 
781 	virtual void getFramebufferDetails(glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format,
782 									   glw::GLenum& out_texture_read_type, glw::GLuint& out_texture_width,
783 									   glw::GLuint& out_texture_height, glw::GLuint& out_texture_pixel_size);
784 
785 	virtual void getRequiredPointSize(glw::GLfloat& out_point_size);
786 
787 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
788 								glw::GLuint&			   out_n_fragment_shader_parts,
789 								const glw::GLchar* const*& out_geometry_shader_parts,
790 								glw::GLuint&			   out_n_geometry_shader_parts,
791 								const glw::GLchar* const*& out_vertex_shader_parts,
792 								glw::GLuint&			   out_n_vertex_shader_parts);
793 
794 	virtual void prepareProgramInput();
795 	virtual bool verifyResult(const void* data);
796 
797 private:
798 	/* Private types */
799 	struct _texture_data
800 	{
801 		glw::GLuint texture_id;
802 		glw::GLint  data;
803 	};
804 	typedef std::vector<_texture_data> textureContainer;
805 
806 	/* Private fields */
807 	/* Shaders' code */
808 	static const glw::GLchar* const m_fragment_shader_code;
809 	static const glw::GLchar* const m_geometry_shader_code_preamble;
810 	static const glw::GLchar* const m_geometry_shader_code_body;
811 	static const glw::GLchar* const m_vertex_shader_code_preamble;
812 	static const glw::GLchar* const m_vertex_shader_code_body;
813 
814 	/* Storage for vertex and geometry shader parts */
815 	const glw::GLchar* m_geometry_shader_parts[3];
816 	const glw::GLchar* m_vertex_shader_parts[3];
817 
818 	/* Framebuffer dimensions */
819 	glw::GLuint				 m_texture_width;
820 	static const glw::GLuint m_texture_height;
821 	static const glw::GLuint m_texture_pixel_size;
822 	static const glw::GLuint m_point_size;
823 
824 	/* Max number of texture units */
825 	glw::GLint  m_max_texture_units;
826 	std::string m_max_texture_units_string;
827 
828 	/* Texture units */
829 	textureContainer m_textures;
830 };
831 
832 /** Implementation of test case 16.8. Test description follows:
833  *
834  *  Make sure it is possible to use as many geometry shader invocations as
835  *  defined by GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT. Verify invocation
836  *  count defaults to 1 if no number of invocations is defined in the
837  *  geometry shader.
838  *
839  *  Category: API.
840  *
841  *  Create a program object and:
842  *
843  *  - A boilerplate vertex shader object;
844  *  - A geometry shader object that:
845  *
846  *  1) takes points on input;
847  *  2) outputs a maximum of 3 vertices making up triangles;
848  *  3) uses exactly GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT invocations;
849  *  4) let:
850  *
851  *              dx = 2.0 / GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT.
852  *
853  *    Emit 3 vertices:
854  *
855  *    4a) (-1+dx*(gl_InvocationID),  -1.001, 0, 1)
856  *    4b) (-1+dx*(gl_InvocationID),   1.001, 0, 1)
857  *    4c) (-1+dx*(gl_InvocationID+1), 1.001, 0, 1)
858  *
859  *  - A fragment shader object that always sets green color for rasterized
860  *   fragments.
861  *
862  *  Compile the shaders, attach them to the program object, link the program
863  *  object.
864  *
865  *  Generate a texture object of type GL_RGBA8 type and of resolution:
866  *
867  *                     (GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT*9)x9
868  *
869  *  Generate a FBO and attach the texture object to its color attachment.
870  *
871  *  Bind the FBO to GL_FRAMEBUFFER target and clear the attachments with red
872  *  color.
873  *
874  *  Generate a vertex array object, bind it.
875  *
876  *  Use the program object and issue a draw call for a single point.
877  *
878  *  Read back texture object data. The test succeeds if correct amount of
879  *  triangles was rendered at expected locations. To test this: :
880  *
881  *  * Let n = (GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT - 1);
882  *  * Let (x1, y1) = ((n)     * 9,     0);
883  *  * Let (x2, y2) = ((n)     * 9,     0);
884  *  * Let (x3, y3) = ((n + 1) * 9 - 1, 9 - 1);
885  *  * Triangle rendered in last invocation is described by vertices at
886  *   coordinates (x_i, y_i) where i e {1, 2, 3}.
887  *  * Centroid of this triangle is defined by (x', y') where:
888  *
889  *                      x' = floor( (x1 + x2 + x3) / 3);
890  *                      y' = floor( (y1 + y2 + y3) / 3);
891  *
892  *  * Pixel at (x',    y') should be set to (0, 255, 0, 0) (allowed epsilon: 0)
893  *  * Pixel at (n*9-1, 9)  should be set to red color      (allowed epsilon: 0)
894  *
895  *  Repeat this test for a geometry shader with no number of invocations
896  *  defined, in which case only one triangle should be rendered.
897  **/
898 class GeometryShaderMaxInvocationsTest : public TestCaseBase
899 {
900 public:
901 	/* Public methods */
902 	GeometryShaderMaxInvocationsTest(Context& context, const ExtParameters& extParams, const char* name,
903 									 const char* description);
904 
~GeometryShaderMaxInvocationsTest()905 	virtual ~GeometryShaderMaxInvocationsTest()
906 	{
907 	}
908 
909 	virtual void		  deinit(void);
910 	virtual IterateResult iterate(void);
911 
912 private:
913 	/* Private methods */
914 	void initTest(void);
915 
916 	/* Verification of results */
917 	bool verifyResultOfMultipleInvocationsPass(unsigned char* result_image);
918 	bool verifyResultOfSingleInvocationPass(unsigned char* result_image);
919 
920 	/* Private fields */
921 	/* Program and shader ids for multiple GS invocations */
922 	glw::GLuint m_fragment_shader_id_for_multiple_invocations_pass;
923 	glw::GLuint m_geometry_shader_id_for_multiple_invocations_pass;
924 	glw::GLuint m_program_object_id_for_multiple_invocations_pass;
925 	glw::GLuint m_vertex_shader_id_for_multiple_invocations_pass;
926 
927 	/* Program and shader ids for single GS invocation */
928 	glw::GLuint m_fragment_shader_id_for_single_invocation_pass;
929 	glw::GLuint m_geometry_shader_id_for_single_invocation_pass;
930 	glw::GLuint m_program_object_id_for_single_invocation_pass;
931 	glw::GLuint m_vertex_shader_id_for_single_invocation_pass;
932 
933 	/* Shaders' code */
934 	static const glw::GLchar* const m_fragment_shader_code;
935 	static const glw::GLchar* const m_geometry_shader_code_preamble;
936 	static const glw::GLchar* const m_geometry_shader_code_layout;
937 	static const glw::GLchar* const m_geometry_shader_code_layout_invocations;
938 	static const glw::GLchar* const m_geometry_shader_code_body;
939 	static const glw::GLchar* const m_vertex_shader_code;
940 
941 	const glw::GLchar* m_geometry_shader_parts_for_multiple_invocations_pass[16];
942 	const glw::GLchar* m_geometry_shader_parts_for_single_invocation_pass[16];
943 
944 	/* Max GS invocations */
945 	glw::GLint m_max_geometry_shader_invocations;
946 
947 	/* String used to store maximum number of GS invocations */
948 	std::string m_max_geometry_shader_invocations_string;
949 
950 	/* Framebuffer */
951 	glw::GLuint m_framebuffer_object_id;
952 	glw::GLuint m_color_texture_id;
953 
954 	/* Framebuffer dimensions */
955 	glw::GLuint				 m_texture_width;
956 	static const glw::GLuint m_triangle_edge_length;
957 	static const glw::GLuint m_texture_height;
958 	static const glw::GLuint m_texture_pixel_size;
959 
960 	/* Vertex array object */
961 	glw::GLuint m_vertex_array_object_id;
962 };
963 
964 /** Implementation of test case 16.9. Test description follows:
965  *
966  *  Make sure it is possible to use up to GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
967  *  texture image units in three different stages, with an assumption that
968  *  each access to the same texture unit from a different stage counts as
969  *  a separate texture unit access.
970  *
971  *  Category: API;
972  *           Functional Test.
973  *
974  *  Create max(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
975  *  GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT, GL_MAX_TEXTURE_IMAGE_UNITS)
976  *  immutable texture objects. Each texture should use GL_R32UI internal
977  *  format, have 1x1 resolution and contain an unique intensity equal to
978  *  index of the texture, where first texture object created is considered
979  *  to have index equal to 1.
980  *
981  *  We want each stage to use at least one texture unit. Use the following
982  *  calculations to determine how many samplers should be defined for each
983  *  stage:
984  *
985  *  1) Vertex stage: n_vertex_smpl = max(1,
986  *    min(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 2,
987  *        GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) ).
988  *  2) Fragment stage: n_frag_smpl = max(1,
989  *    min(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - n_vertex_smpl - 1,
990  *        GL_MAX_TEXTURE_IMAGE_UNITS) )
991  *  3) Geometry shader: n_geom_smpl = max(1,
992  *    min(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - n_vertex_smpl - n_frag_smpl,
993  *        GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT) )
994  *
995  *  Create a program object and fragment, geometry and vertex shader objects:
996  *
997  *  - Vertex shader object should define exactly n_vertex_smpl 2D texture
998  *   samplers named samplerX where X stands for texture unit index that
999  *   will be accessed. It should set gl_Position to:
1000  *
1001  *     (-1 + gl_VertexID / GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, -1, 0, 1)
1002  *
1003  *  Vertex shader should define int output variable out_vs_vertexid storing
1004  *  gl_VertexID value, and an output integer variable out_vs_vertex that
1005  *  should be written result of the following computation:
1006  *
1007  *  sum(i=0..n_vertex_smpl)( (gl_VertexID == i) * (value sampled from the
1008  *  texture sampler samplerX)) where: X = i;
1009  *
1010  *  - Geometry shader object should define exactly n_geom_smpl 2D texture
1011  *   samplers named samplerX where X stands for texture unit index that
1012  *   will be accessed. The geometry shader should define int input variables
1013  *   out_vs_vertexid, out_vs_vertex and int output variables:
1014  *
1015  *  * out_gs_vertexid - set to the value of out_vs_vertexid;
1016  *  * out_gs_vertex   - set to the value of out_vs_vertex;
1017  *  * out_geometry that should be written result of the following computation:
1018  *
1019  *  sum(i=0..n_geom_smpl)( (out_vs_vertexid == i) * (value sampled from the
1020  *  texture sampler samplerX)) where: X = i;
1021  *
1022  *  The geometry shader should emit exactly one point at position configured
1023  *  by vertex shader. The geometry shader should take points as input.
1024  *
1025  *  - Fragment shader object should define exactly n_frag_smpl 2D texture
1026  *   samplers named samplerX where X stands for texture unit index that
1027  *   will be accessed. The fragment shader should define int input variables
1028  *   out_gs_vertexid, out_gs_vertex and out_geometry. It should define
1029  *   a single int output variable result which should be written result of
1030  *   the following computation:
1031  *
1032  *  if (out_gs_vertex == out_geometry)
1033  *  {
1034  *     set to sum(i=0..n_frag_smpl)(out_gs_vertex_id == i) * (value sampled
1035  *     from the texture sampler samplerX)) where: X = i;
1036  *  }
1037  *  else
1038  *  {
1039  *     set to 0.
1040  *  }
1041  *
1042  *  The shaders should be attached to the program object and compiled. The
1043  *  program object should be linked.
1044  *
1045  *  Assume:
1046  *
1047  *  min_texture_image_units = min(
1048  *  GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
1049  *  GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
1050  *
1051  *  A framebuffer object should be created, along with a 2D texture object of
1052  *  min_texture_image_units x 1 resolution. The texture object should be
1053  *  attached to color attachment point of the FBO. Bind the framebuffer object
1054  *  to GL_DRAW_FRAMEBUFFER target.
1055  *
1056  *  A vertex array object should be created and bound.
1057  *
1058  *  Configure the program object's uniform samplers to use consecutive texture
1059  *  image units. Bind the texture objects we created at the beginning to these
1060  *  texture units. Draw exactly min_texture_image_units points.
1061  *
1062  *  Bind the FBO to GL_READ_FRAMEBUFFER. Read the rendered data and make sure
1063  *  the result values form a (1, 2, ... min_texture_image_units) set.
1064  **/
1065 class GeometryShaderMaxCombinedTextureUnitsTest : public GeometryShaderLimitsRenderingBase
1066 {
1067 public:
1068 	/* Public methods */
1069 	GeometryShaderMaxCombinedTextureUnitsTest(Context& context, const ExtParameters& extParams, const char* name,
1070 											  const char* description);
1071 
~GeometryShaderMaxCombinedTextureUnitsTest()1072 	virtual ~GeometryShaderMaxCombinedTextureUnitsTest()
1073 	{
1074 	}
1075 
1076 protected:
1077 	/* Methods overriden from GeometryShaderLimitsRenderingBase */
1078 	virtual void clean();
1079 
1080 	virtual void getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices);
1081 
1082 	virtual void getFramebufferDetails(glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format,
1083 									   glw::GLenum& out_texture_read_type, glw::GLuint& out_texture_width,
1084 									   glw::GLuint& out_texture_height, glw::GLuint& out_texture_pixel_size);
1085 
1086 	virtual void getRequiredPointSize(glw::GLfloat& out_point_size);
1087 
1088 	virtual void getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts,
1089 								glw::GLuint&			   out_n_fragment_shader_parts,
1090 								const glw::GLchar* const*& out_geometry_shader_parts,
1091 								glw::GLuint&			   out_n_geometry_shader_parts,
1092 								const glw::GLchar* const*& out_vertex_shader_parts,
1093 								glw::GLuint&			   out_n_vertex_shader_parts);
1094 
1095 	virtual void prepareProgramInput();
1096 	virtual bool verifyResult(const void* data);
1097 
1098 private:
1099 	/* Private types */
1100 	struct _texture_data
1101 	{
1102 		glw::GLuint texture_id;
1103 		glw::GLuint data;
1104 	};
1105 	typedef std::vector<_texture_data> textureContainer;
1106 
1107 	/* Private fields */
1108 	/* Shaders' code */
1109 	static const glw::GLchar* const m_fragment_shader_code_preamble;
1110 	static const glw::GLchar* const m_fragment_shader_code_body;
1111 	static const glw::GLchar* const m_geometry_shader_code_preamble;
1112 	static const glw::GLchar* const m_geometry_shader_code_body;
1113 	static const glw::GLchar* const m_vertex_shader_code_preamble;
1114 	static const glw::GLchar* const m_vertex_shader_code_body;
1115 
1116 	/* Storage for vertex and geometry shader parts */
1117 	const glw::GLchar* m_fragment_shader_parts[3];
1118 	const glw::GLchar* m_geometry_shader_parts[3];
1119 	const glw::GLchar* m_vertex_shader_parts[3];
1120 
1121 	/* Framebuffer dimensions */
1122 	glw::GLuint				 m_texture_width;
1123 	static const glw::GLuint m_texture_height;
1124 	static const glw::GLuint m_texture_pixel_size;
1125 	static const glw::GLuint m_point_size;
1126 
1127 	/* Max number of texture units */
1128 	glw::GLint  m_max_combined_texture_units;
1129 	glw::GLint  m_max_fragment_texture_units;
1130 	glw::GLint  m_max_geometry_texture_units;
1131 	glw::GLint  m_max_vertex_texture_units;
1132 	glw::GLint  m_min_texture_units;
1133 	glw::GLint  m_n_fragment_texture_units;
1134 	glw::GLint  m_n_geometry_texture_units;
1135 	glw::GLint  m_n_texture_units;
1136 	glw::GLint  m_n_vertex_texture_units;
1137 	std::string m_n_fragment_texture_units_string;
1138 	std::string m_n_geometry_texture_units_string;
1139 	std::string m_n_vertex_texture_units_string;
1140 
1141 	/* Texture units */
1142 	textureContainer m_textures;
1143 };
1144 
1145 } /* glcts */
1146 
1147 #endif // _ESEXTCGEOMETRYSHADERLIMITS_HPP
1148