• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ESEXTCGEOMETRYSHADERRENDERING_HPP
2 #define _ESEXTCGEOMETRYSHADERRENDERING_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 
31 /** Supported geometry shader output layout qualifiers */
32 typedef enum {
33 	/* points */
34 	SHADER_OUTPUT_TYPE_POINTS,
35 	/* lines */
36 	SHADER_OUTPUT_TYPE_LINE_STRIP,
37 	/* triangles */
38 	SHADER_OUTPUT_TYPE_TRIANGLE_STRIP,
39 
40 	/* Always last */
41 	SHADER_OUTPUT_TYPE_COUNT
42 } _shader_output_type;
43 
44 /** Implements Geometry Shader conformance test group 1.
45  *
46  *  Note that actual testing is handled by classes implementing GeometryShaderRenderingCase
47  *  interface. This class implements DEQP CTS test case interface, meaning it is only
48  *  responsible for executing the test and reporting the results back to CTS.
49  *
50  **/
51 class GeometryShaderRendering : public TestCaseGroupBase
52 {
53 public:
54 	/* Public methods */
55 	GeometryShaderRendering(Context& context, const ExtParameters& extParams, const char* name,
56 							const char* description);
57 
~GeometryShaderRendering()58 	virtual ~GeometryShaderRendering()
59 	{
60 	}
61 
62 	virtual void init(void);
63 
64 private:
65 	/* Private type definitions */
66 	typedef enum {
67 		/* points */
68 		SHADER_INPUT_POINTS,
69 
70 		/* lines */
71 		SHADER_INPUT_LINES,
72 
73 		/* lines_with_adjacency */
74 		SHADER_INPUT_LINES_WITH_ADJACENCY,
75 
76 		/* triangles */
77 		SHADER_INPUT_TRIANGLES,
78 
79 		/* triangles_with_adjacency */
80 		SHADER_INPUT_TRIANGLES_WITH_ADJACENCY,
81 
82 		/* Always last */
83 		SHADER_INPUT_UNKNOWN
84 	} _shader_input;
85 
86 	/* Private methods */
87 	const char* getTestName(_shader_input input, _shader_output_type output_type, glw::GLenum drawcall_mode);
88 };
89 
90 /* Defines an interface that all test case classes must implement.
91  *
92  * Base implementation initializes GLES objects later used in the specific test
93  * and fills them with content, as reported by actual test case implementations.
94  *
95  * Instances matching this interface are used by GeometryShaderRendering class
96  * to execute a set of all the tests as defined in the test specification.
97  */
98 class GeometryShaderRenderingCase : public TestCaseBase
99 {
100 public:
101 	/* Public type definitions */
102 	/** Supported draw call types. */
103 	typedef enum {
104 		/* glDrawArrays() */
105 		DRAW_CALL_TYPE_GL_DRAW_ARRAYS,
106 
107 		/* glDrawArraysInstanced() */
108 		DRAW_CALL_TYPE_GL_DRAW_ARRAYS_INSTANCED,
109 
110 		/* glDrawElements() */
111 		DRAW_CALL_TYPE_GL_DRAW_ELEMENTS,
112 
113 		/* glDrawElementsInstanced() */
114 		DRAW_CALL_TYPE_GL_DRAW_ELEMENTS_INSTANCED,
115 
116 		/* glDrawRangeElements() */
117 		DRAW_CALL_TYPE_GL_DRAW_RANGE_ELEMENTS
118 
119 	} _draw_call_type;
120 
121 	/* Public methods */
122 	GeometryShaderRenderingCase(Context& Context, const ExtParameters& extParams, const char* name,
123 								const char* description);
124 
~GeometryShaderRenderingCase()125 	virtual ~GeometryShaderRenderingCase()
126 	{
127 	}
128 
129 	virtual void deinit();
130 	void executeTest(_draw_call_type type);
131 	virtual IterateResult iterate();
132 
133 protected:
134 	/* Protected methods */
135 	void				 initTest();
136 	virtual unsigned int getAmountOfDrawInstances()				   = 0;
137 	virtual unsigned int getAmountOfElementsPerInstance()		   = 0;
138 	virtual unsigned int getAmountOfVerticesPerInstance()		   = 0;
139 	virtual glw::GLenum  getDrawCallMode()						   = 0;
140 	virtual std::string  getFragmentShaderCode()				   = 0;
141 	virtual std::string  getGeometryShaderCode()				   = 0;
142 	virtual glw::GLuint getRawArraysDataBufferSize(bool instanced) = 0;
143 	virtual const void* getRawArraysDataBuffer(bool instanced)	 = 0;
144 	virtual void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height) = 0;
145 	virtual glw::GLuint getUnorderedArraysDataBufferSize(bool instanced)   = 0;
146 	virtual const void* getUnorderedArraysDataBuffer(bool instanced)	   = 0;
147 	virtual glw::GLuint getUnorderedElementsDataBufferSize(bool instanced) = 0;
148 	virtual const void* getUnorderedElementsDataBuffer(bool instanced)	 = 0;
149 	virtual glw::GLenum  getUnorderedElementsDataType()					   = 0;
150 	virtual glw::GLubyte getUnorderedElementsMaxIndex()					   = 0;
151 	virtual glw::GLubyte getUnorderedElementsMinIndex()					   = 0;
152 	virtual std::string  getVertexShaderCode()							   = 0;
153 	virtual void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data) = 0;
154 
setUniformsBeforeDrawCall(_draw_call_type)155 	virtual void setUniformsBeforeDrawCall(_draw_call_type /*drawcall_type*/)
156 	{
157 	}
158 
159 	/* Protected variables */
160 	deqp::Context& m_context;
161 	glw::GLuint	m_instanced_raw_arrays_bo_id;
162 	glw::GLuint	m_instanced_unordered_arrays_bo_id;
163 	glw::GLuint	m_instanced_unordered_elements_bo_id;
164 	glw::GLuint	m_noninstanced_raw_arrays_bo_id;
165 	glw::GLuint	m_noninstanced_unordered_arrays_bo_id;
166 	glw::GLuint	m_noninstanced_unordered_elements_bo_id;
167 	glw::GLuint	m_fs_id;
168 	glw::GLuint	m_gs_id;
169 	glw::GLuint	m_po_id;
170 	glw::GLuint	m_renderingTargetSize_uniform_location;
171 	glw::GLuint	m_singleRenderingTargetSize_uniform_location;
172 	glw::GLuint	m_vao_id;
173 	glw::GLuint	m_vs_id;
174 
175 	glw::GLuint m_fbo_id;
176 	glw::GLuint m_read_fbo_id;
177 	glw::GLuint m_to_id;
178 
179 	glw::GLuint m_instanced_fbo_id;
180 	glw::GLuint m_instanced_read_fbo_id;
181 	glw::GLuint m_instanced_to_id;
182 };
183 
184 /** Implements Geometry Shader conformance test group 1, 'points' input primitive type case.
185  *  Test specification for this case follows:
186  *
187  *  All sub-tests assume point size & line width of 1 pixel, which is the
188  *  minimum maximum value for both properties in GLES 3.0.
189  *
190  *  Let (R, G, B, A) be the color of the  input point that is to be amplified.
191  *  Color buffer should be cleared with (0, 0, 0, 0) prior to executing each
192  *  of the scenarios.
193  *
194  *  1.1. If "points" output primitive type is used:
195  *
196  *  The geometry shader should emit 9 points in total for a single input.
197  *  Each point should be assigned  a size of 1. The points should be
198  *  positioned, so that they tightly surround the "input" point from left /
199  *  right / top / left sides, as well as from top-left / top-right /
200  *  bottom-left / bottom-right corners but do *not* overlap in screen-space.
201  *
202  *  Additional points should also use (R, G, B, A) color.
203  *
204  *  The test should draw 8 points (one after another, assume a horizontal
205  *  delta of 2 pixels) of varying colors to a 2D texture of resolution 38x3.
206  *  Test succeeds if centers of all emitted points have colors different than
207  *  the background color.
208  *
209  *  1.2. If "lines" output primitive type is used:
210  *
211  *  The geometry shader should draw outlines (built of line segments) of
212  *  three quads nested within each other, as depicted below:
213  *
214  *                           1 1 1 1 1 1 1
215  *                           1 2 2 2 2 2 1
216  *                           1 2 3 3 3 2 1
217  *                           1 2 3 * 3 2 1
218  *                           1 2 3 3 3 2 1
219  *                           1 2 2 2 2 2 1
220  *                           1 1 1 1 1 1 1
221  *
222  *  where each number corresponds to index of the quad and * indicates
223  *  position of the input point which is not drawn.
224  *
225  *  Each quad should be drawn with (R, G, B, A) color.
226  *  The test should draw 8 points (one after another) of varying colors to
227  *  a 2D texture of resolution 54x7. Test succeeds if all pixels making up
228  *  the central quad 2 have valid colors.
229  *
230  *  1.3. If "triangles" output primitive type is used:
231  *
232  *  The geometry shader should generate 2 triangle primitives for a single
233  *  input point:
234  *
235  *  * A) (Bottom-left corner, top-left corner, bottom-right corner), use
236  *       (R, 0, 0, 0) color;
237  *  * B) (Bottom-right corner, top-left corner, top-right corner), use
238  *       (0, G, 0, 0) color;
239  *
240  *  The test should draw 8 points (one after another) of varying colors to
241  *  a 2D texture of resolution of resolution 48x6. Test succeeds if centers
242  *  of the rendered triangles have valid colors.
243  *
244  **/
245 class GeometryShaderRenderingPointsCase : public GeometryShaderRenderingCase
246 {
247 public:
248 	/* Public methods */
249 	GeometryShaderRenderingPointsCase(Context& context, const ExtParameters& extParams, const char* name,
250 									  glw::GLenum drawcall_mode, _shader_output_type output_type);
251 
252 	virtual ~GeometryShaderRenderingPointsCase();
253 
254 protected:
255 	/* GeometryShaderRenderingCase interface implementation */
256 	unsigned int getAmountOfDrawInstances();
257 	unsigned int getAmountOfElementsPerInstance();
258 	unsigned int getAmountOfVerticesPerInstance();
259 	glw::GLenum  getDrawCallMode();
260 	std::string  getFragmentShaderCode();
261 	std::string  getGeometryShaderCode();
262 	glw::GLuint getRawArraysDataBufferSize(bool instanced);
263 	const void* getRawArraysDataBuffer(bool instanced);
264 	void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height);
265 	glw::GLuint getUnorderedArraysDataBufferSize(bool instanced);
266 	const void* getUnorderedArraysDataBuffer(bool instanced);
267 	glw::GLuint getUnorderedElementsDataBufferSize(bool instanced);
268 	const void* getUnorderedElementsDataBuffer(bool instanced);
269 	glw::GLenum  getUnorderedElementsDataType();
270 	glw::GLubyte getUnorderedElementsMaxIndex();
271 	glw::GLubyte getUnorderedElementsMinIndex();
272 	std::string  getVertexShaderCode();
273 	void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data);
274 
275 private:
276 	/* Private variables */
277 	_shader_output_type m_output_type;
278 
279 	float*		   m_raw_array_data;
280 	float*		   m_unordered_array_data;
281 	unsigned char* m_unordered_elements_data;
282 };
283 
284 /** Implements Geometry Shader conformance test group 1, 'lines' and
285  *  'lines_adjacency' input primitive type cases.
286  *
287  *  Test specification for this case follows:
288  *
289  *  Assume a point size of 1 pixel and line width of 1 pixel, where
290  *  appropriate.
291  *  Let (R, G, B, A) be the color of start point of the input line and
292  *  (R', G', B', A') be the color of end point of the input line.
293  *
294  *  2.1. If "points" output primitive type is used:
295  *
296  *  The geometry shader should generate 8 points for a single input line segment,
297  *  where each point consists of 9 sub-points tightly forming a quad (with
298  *  the actual point located in the center) in order to emulate larger point
299  *  size. The points should be uniformly distributed over the primitive
300  *  (first point positioned at the start point and the last one located at
301  *  the end point) and their color should linearly interpolate from the
302  *  (R, G, B, A) to (R', G', B', A'). All sub-points should use the same
303  *  color as the parent point.
304  *
305  *  The test should draw the points over a square outline. Each instance should
306  *  draw a set of points occupying a separate outline. Each rectangle should
307  *  occupy a block of 45x45.
308  *
309  *  Test succeeds if centers of generated points have valid colors.
310  *
311  *  2.2. If "lines" output primitive type is used:
312  *
313  *  Expanding on the idea presenting in 2.1, for each line segment the GS
314  *  should generate three line segments, as presented below:
315  *
316  *                       Upper/left helper line segment
317  *                       Line segment
318  *                       Bottom/right helper line segment
319  *
320  *  This is to emulate a larger line width than the minimum maximum line
321  *  width all GLES implementations must support.
322  *
323  *  Upper helper line segment should use start point's color;
324  *  Middle line segment should take mix(start_color, end_color, 0.5) color;
325  *  Bottom helper line segment should use end point's color;
326  *
327  *  Test succeeds if all pixels of generated middle line segments have valid
328  *  colors. Do not test corners.
329  *
330  *  2.3. If "triangles" output primitive type is used:
331  *
332  *  Expanding on the idea presented in 2.1: for each input line segment,
333  *  the GS should generate a triangle, using two vertices provided and
334  *  (0, 0, 0, 1). By drawing a quad outline, whole screen-space should be
335  *  covered with four triangles.
336  *  The test passes if centroids of the generated triangles carry valid colors.
337  *
338  **/
339 class GeometryShaderRenderingLinesCase : public GeometryShaderRenderingCase
340 {
341 public:
342 	/* Public methods */
343 	GeometryShaderRenderingLinesCase(Context& context, const ExtParameters& extParams, const char* name,
344 									 bool use_adjacency_data, glw::GLenum drawcall_mode,
345 									 _shader_output_type output_type);
346 
347 	virtual ~GeometryShaderRenderingLinesCase();
348 
349 protected:
350 	/* GeometryShaderRenderingCase interface implementation */
351 	unsigned int getAmountOfDrawInstances();
352 	unsigned int getAmountOfElementsPerInstance();
353 	unsigned int getAmountOfVerticesPerInstance();
354 	glw::GLenum  getDrawCallMode();
355 	std::string  getFragmentShaderCode();
356 	std::string  getGeometryShaderCode();
357 	glw::GLuint getRawArraysDataBufferSize(bool instanced);
358 	const void* getRawArraysDataBuffer(bool instanced);
359 	void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height);
360 	glw::GLuint getUnorderedArraysDataBufferSize(bool instanced);
361 	const void* getUnorderedArraysDataBuffer(bool instanced);
362 	glw::GLuint getUnorderedElementsDataBufferSize(bool instanced);
363 	const void* getUnorderedElementsDataBuffer(bool instanced);
364 	glw::GLenum  getUnorderedElementsDataType();
365 	glw::GLubyte getUnorderedElementsMaxIndex();
366 	glw::GLubyte getUnorderedElementsMinIndex();
367 	std::string  getVertexShaderCode();
368 	void setUniformsBeforeDrawCall(_draw_call_type drawcall_type);
369 	void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data);
370 
371 private:
372 	/* Private variables */
373 	_shader_output_type m_output_type;
374 
375 	glw::GLenum m_drawcall_mode;
376 	bool		m_use_adjacency_data;
377 
378 	float*		 m_raw_array_instanced_data;
379 	unsigned int m_raw_array_instanced_data_size;
380 	float*		 m_raw_array_noninstanced_data;
381 	unsigned int m_raw_array_noninstanced_data_size;
382 
383 	float*		 m_unordered_array_instanced_data;
384 	unsigned int m_unordered_array_instanced_data_size;
385 	float*		 m_unordered_array_noninstanced_data;
386 	unsigned int m_unordered_array_noninstanced_data_size;
387 
388 	unsigned char* m_unordered_elements_instanced_data;
389 	unsigned int   m_unordered_elements_instanced_data_size;
390 	unsigned char* m_unordered_elements_noninstanced_data;
391 	unsigned int   m_unordered_elements_noninstanced_data_size;
392 
393 	unsigned char m_unordered_elements_max_index;
394 	unsigned char m_unordered_elements_min_index;
395 };
396 
397 /** Implements Geometry Shader conformance test group 1, 'triangles' and
398  *  'triangles_adjacency' input primitive type cases. Test specification
399  *  for this case follows:
400  *
401  *  All tests should draw a 45-degree rotated square shape consisting of four
402  *  separate triangles, as depicted in the picture below:
403  *
404  *
405  *                                 C
406  *                                / \
407      *                               /   \
408      *                              B--A--D
409  *                               \   /
410  *                                \_/
411  *                                 E
412  *
413  *  For GL_TRIANGLES data, the rendering order is: ABC, ACD, ADE, AEB;
414  *  For GL_TRIANGLE_FAN,   the rendering order is: ABCDEB;
415  *  For GL_TRIANGLE_STRIP, the rendering order is: BACDAEB;
416  *
417  *  Note that for triangle strips, a degenerate triangle will be rendered.
418  *  Test implementation should not test the first triangle rendered in the
419  *  top-right quarter, as it will be overwritten by the triangle that follows
420  *  right after.
421  *
422  *  Subsequent draw call instances should draw the geometry one after another,
423  *  in vertical direction.
424  *
425  *  Each of the tests should use 29x(29 * number of instances) resolution for
426  *  the rendertarget.
427  *
428  *  3.1. If "points" output primitive type is used:
429  *
430  *  The geometry shader should generate 3 points for a single input triangle.
431  *  These points should be emitted for each of the triangle's vertex
432  *  locations and:
433  *
434  *  * First vertex should be of (R, G, B, A) color;
435  *  * Second vertex should be of (R', G', B', A') color;
436  *  * Third vertex should be of (R'', G'', B'', A'') color;
437  *
438  *  Each point should actually consist of 9 emitted points of size 1 (as
439  *  described in test scenario 1.1), with the middle point being positioned
440  *  at exact vertex location. This is to emulate larger point size than the
441  *  minimum maximum allows. All emitted points should use the same color as
442  *  parent point's.
443  *
444  *  Test succeeds if centers of the rendered points have valid colors.
445  *
446  *  3.2. If "lines" output primitive type is used:
447  *
448  *  Let:
449  *
450  *  * TL represent top-left corner of the triangle's bounding box;
451  *  * TR represent top-right corner of the triangle's bounding box;
452  *  * BL represent bottom-left corner of the triangle's bounding box;
453  *  * BR represent bottom-right corner of the triangle's bounding box;
454  *
455  *  The geometry shader should draw 4 line segments for a single input
456  *  triangle:
457  *
458  *  * First line segment should start at BL and end at TL and use a static
459  *    (R, G, B, A) color;
460  *  * Second line segment should start at TL and end at TR and use a static
461  *    (R', G', B', A') color;
462  *  * Third line segment should start at TR and end at BR and use a static
463  *    (R'', G'', B'', A'') color;
464  *  * Fourth line segment should start at BR and end at BL and use a static
465  *    (R, G', B'', A) color;
466  *
467  *  Each line segment should actually consist of 3 separate line segments
468  *  "stacked" on top of each other, with the middle segment being positioned
469  *  as described above (as described in test scenario 2.2). This is to
470  *  emulate line width that is larger than the minimum maximum allows. All
471  *  emitted line segments should use the same color as parent line segment's.
472  *
473  *  Test succeeds if centers of the rendered line segments have valid colors.
474  *
475  *  3.3. If "triangles" output primitive type is used:
476  *
477  *  Test should take incoming triangle vertex locations and order them in the
478  *  following order:
479  *
480  *  a) A - vertex in the origin;
481  *  b) B - the other vertex located on the same height as A;
482  *  c) C - remaining vertex;
483  *
484  *  Let D = BC/2.
485  *
486  *  The test should emit ABD and ACD triangles for input ABC triangle data.
487  *  First triangle emitted should take color of the first input vertex
488  *  (not necessarily A!).
489  *  The second one should use third vertex's color (not necessarily C!),
490  *  with the first channel being multiplied by two.
491  *
492  *  Test succeeds if centers of the rendered triangles have valid colors;
493  *
494  **/
495 class GeometryShaderRenderingTrianglesCase : public GeometryShaderRenderingCase
496 {
497 public:
498 	/* Public methods */
499 	GeometryShaderRenderingTrianglesCase(Context& context, const ExtParameters& extParams, const char* name,
500 										 bool use_adjacency_data, glw::GLenum drawcall_mode,
501 										 _shader_output_type output_type);
502 
503 	virtual ~GeometryShaderRenderingTrianglesCase();
504 
505 protected:
506 	/* GeometryShaderRenderingCase interface implementation */
507 	unsigned int getAmountOfDrawInstances();
508 	unsigned int getAmountOfElementsPerInstance();
509 	unsigned int getAmountOfVerticesPerInstance();
510 	glw::GLenum  getDrawCallMode();
511 	std::string  getFragmentShaderCode();
512 	std::string  getGeometryShaderCode();
513 	glw::GLuint getRawArraysDataBufferSize(bool instanced);
514 	const void* getRawArraysDataBuffer(bool instanced);
515 	void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height);
516 	glw::GLuint getUnorderedArraysDataBufferSize(bool instanced);
517 	const void* getUnorderedArraysDataBuffer(bool instanced);
518 	glw::GLuint getUnorderedElementsDataBufferSize(bool instanced);
519 	const void* getUnorderedElementsDataBuffer(bool instanced);
520 	glw::GLenum  getUnorderedElementsDataType();
521 	glw::GLubyte getUnorderedElementsMaxIndex();
522 	glw::GLubyte getUnorderedElementsMinIndex();
523 	std::string  getVertexShaderCode();
524 	void setUniformsBeforeDrawCall(_draw_call_type drawcall_type);
525 	void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data);
526 
527 private:
528 	/* Private variables */
529 	_shader_output_type m_output_type;
530 
531 	glw::GLenum m_drawcall_mode;
532 	bool		m_use_adjacency_data;
533 
534 	float*		 m_raw_array_instanced_data;
535 	unsigned int m_raw_array_instanced_data_size;
536 	float*		 m_raw_array_noninstanced_data;
537 	unsigned int m_raw_array_noninstanced_data_size;
538 
539 	float*		 m_unordered_array_instanced_data;
540 	unsigned int m_unordered_array_instanced_data_size;
541 	float*		 m_unordered_array_noninstanced_data;
542 	unsigned int m_unordered_array_noninstanced_data_size;
543 
544 	unsigned char* m_unordered_elements_instanced_data;
545 	unsigned int   m_unordered_elements_instanced_data_size;
546 	unsigned char* m_unordered_elements_noninstanced_data;
547 	unsigned int   m_unordered_elements_noninstanced_data_size;
548 
549 	unsigned char m_unordered_elements_max_index;
550 	unsigned char m_unordered_elements_min_index;
551 };
552 
553 } // namespace glcts
554 
555 #endif // _ESEXTCGEOMETRYSHADERRENDERING_HPP
556