• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GL4CPIPELINESTATISTICSQUERYTESTS_HPP
2 #define _GL4CPIPELINESTATISTICSQUERYTESTS_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  */ /*!
28  * \file  gl4c PipelineStatisticsQueryTests.hpp
29  * \brief Declares test classes that verify conformance of the
30  *        GL implementation with GL_ARB_pipeline_statistics_query
31  *        extension specification.
32  */ /*-------------------------------------------------------------------*/
33 
34 #include "glcTestCase.hpp"
35 #include "glwDefs.hpp"
36 #include "tcuDefs.hpp"
37 #include <limits.h>
38 #include <sstream>
39 #include <string.h>
40 
41 namespace glcts
42 {
43 class PipelineStatisticsQueryUtilities
44 {
45 public:
46 	/* Public type definitions */
47 	typedef bool (*PFNQUERYDRAWHANDLERPROC)(void* user_arg);
48 
49 	/* Type of the draw call used for a test iteration */
50 	enum _draw_call_type
51 	{
52 		/* glDrawArrays() */
53 		DRAW_CALL_TYPE_GLDRAWARRAYS,
54 		/* glDrawArraysIndirect() */
55 		DRAW_CALL_TYPE_GLDRAWARRAYSINDIRECT,
56 		/* glDrawArraysInstanced() */
57 		DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCED,
58 		/* glDrawArraysInstancedBaseInstance() */
59 		DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCEDBASEINSTANCE,
60 		/* glDrawElements() */
61 		DRAW_CALL_TYPE_GLDRAWELEMENTS,
62 		/* glDrawElementsBaseVertex() */
63 		DRAW_CALL_TYPE_GLDRAWELEMENTSBASEVERTEX,
64 		/* glDrawElementsIndirect() */
65 		DRAW_CALL_TYPE_GLDRAWELEMENTSINDIRECT,
66 		/* glDrawElementsInstanced() */
67 		DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCED,
68 		/* glDrawElementsInstancedBaseInstance() */
69 		DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEINSTANCE,
70 		/* glDrawElementsInstancedBaseVertexBaseInstance() */
71 		DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE,
72 		/* glDrawRangeElements() */
73 		DRAW_CALL_TYPE_GLDRAWRANGEELEMENTS,
74 		/* glDrawRangeElementsBaseVertex() */
75 		DRAW_CALL_TYPE_GLDRAWRANGEELEMENTSBASEVERTEX,
76 
77 		/* Always last */
78 		DRAW_CALL_TYPE_COUNT
79 	};
80 
81 	/* Input primitive type defined in geometry shader body used by a test iteration */
82 	enum _geometry_shader_input
83 	{
84 		GEOMETRY_SHADER_INPUT_FIRST,
85 
86 		GEOMETRY_SHADER_INPUT_POINTS = GEOMETRY_SHADER_INPUT_FIRST,
87 		GEOMETRY_SHADER_INPUT_LINES,
88 		GEOMETRY_SHADER_INPUT_LINES_ADJACENCY,
89 		GEOMETRY_SHADER_INPUT_TRIANGLES,
90 		GEOMETRY_SHADER_INPUT_TRIANGLES_ADJACENCY,
91 
92 		/* Always last */
93 		GEOMETRY_SHADER_INPUT_COUNT
94 	};
95 
96 	/* Output primitive type defined in geometry shader body used by a test iteration */
97 	enum _geometry_shader_output
98 	{
99 		GEOMETRY_SHADER_OUTPUT_FIRST,
100 
101 		GEOMETRY_SHADER_OUTPUT_POINTS = GEOMETRY_SHADER_OUTPUT_FIRST,
102 		GEOMETRY_SHADER_OUTPUT_LINE_STRIP,
103 		GEOMETRY_SHADER_OUTPUT_TRIANGLE_STRIP,
104 
105 		/* Always last */
106 		GEOMETRY_SHADER_OUTPUT_COUNT
107 	};
108 
109 	/* Primitive type used for a draw call */
110 	enum _primitive_type
111 	{
112 		PRIMITIVE_TYPE_FIRST,
113 
114 		/* GL_POINTS */
115 		PRIMITIVE_TYPE_POINTS = PRIMITIVE_TYPE_FIRST,
116 		/* GL_LINE_LOOP */
117 		PRIMITIVE_TYPE_LINE_LOOP,
118 		/* GL_LINE_STRIP */
119 		PRIMITIVE_TYPE_LINE_STRIP,
120 		/* GL_LINES */
121 		PRIMITIVE_TYPE_LINES,
122 		/* GL_LINES_ADJACENCY */
123 		PRIMITIVE_TYPE_LINES_ADJACENCY,
124 		/* GL_PATCHES */
125 		PRIMITIVE_TYPE_PATCHES,
126 		/* GL_TRIANGLE_FAN */
127 		PRIMITIVE_TYPE_TRIANGLE_FAN,
128 		/* GL_TRIANGLE_STRIP */
129 		PRIMITIVE_TYPE_TRIANGLE_STRIP,
130 		/* GL_TRIANGLES */
131 		PRIMITIVE_TYPE_TRIANGLES,
132 		/* GL_TRIANGLES_ADJACENCY */
133 		PRIMITIVE_TYPE_TRIANGLES_ADJACENCY,
134 
135 		/* Always last */
136 		PRIMITIVE_TYPE_COUNT
137 	};
138 
139 	/* Stores result of a single test iteration. */
140 	struct _test_execution_result
141 	{
142 		/* true if 64-bit signed integer counter value was retrieved for the iteration,
143 		 * false otherwise.
144 		 */
145 		bool int64_written;
146 		/* true if 64-bit unsigned integer counter value was retrieved for the iteration,
147 		 * false otherwise.
148 		 */
149 		bool uint64_written;
150 
151 		/* 32-bit signed integer counter value, as stored in the query buffer object
152 		 * used for the test iteration. This variable will only be modified if query
153 		 * buffer objects are supported.
154 		 */
155 		glw::GLint result_qo_int;
156 		/* 64-bit signed integer counter value, as stored in the query buffer object
157 		 * used for the test iteration. This variable will only be modified if query
158 		 * buffer objects are supported, and int64_written is true.
159 		 */
160 		glw::GLint64 result_qo_int64;
161 		/* 32-bit unsigned integer counter value, as stored in the query buffer object
162 		 * used for the test iteration. This variable will only be modified if query
163 		 * buffer objects are supported.
164 		 */
165 		glw::GLuint result_qo_uint;
166 		/* 64-bit unsigned integer counter value, as stored in the query buffer object
167 		 * used for the test iteration. This variable will only be modified if query
168 		 * buffer objects are supported, and uint64_written is true.
169 		 */
170 		glw::GLuint64 result_qo_uint64;
171 
172 		/* 32-bit signed integer counter value, as stored in the query object
173 		 * used for the test iteration.
174 		 */
175 		glw::GLint result_int;
176 		/* 64-bit signed integer counter value, as stored in the query object
177 		 * used for the test iteration. Only set if int64_written is true.
178 		 */
179 		glw::GLint64 result_int64;
180 		/* 32-bit unsigned integer counter value, as stored in the query object
181 		 * used for the test iteration.
182 		 */
183 		glw::GLuint result_uint;
184 		/* 64-bit unsigned integer counter value, as stored in the query object
185 		 * used for the test iteration. Only set if uint64_written is true.
186 		 */
187 		glw::GLuint64 result_uint64;
188 
189 		/* Constructor */
_test_execution_resultglcts::PipelineStatisticsQueryUtilities::_test_execution_result190 		_test_execution_result()
191 		{
192 			result_qo_int	= INT_MAX;
193 			result_qo_int64  = LLONG_MAX;
194 			result_qo_uint   = UINT_MAX;
195 			result_qo_uint64 = ULLONG_MAX;
196 
197 			result_int	= INT_MAX;
198 			result_int64  = LLONG_MAX;
199 			result_uint   = UINT_MAX;
200 			result_uint64 = ULLONG_MAX;
201 
202 			int64_written  = false;
203 			uint64_written = false;
204 		}
205 	};
206 
207 	/* Tells how the result values should be verified against
208 	 * the reference value.
209 	 */
210 	enum _verification_type
211 	{
212 		/* The result value should be equal to the reference value */
213 		VERIFICATION_TYPE_EXACT_MATCH,
214 		/* The result value should be equal or larger than the reference value */
215 		VERIFICATION_TYPE_EQUAL_OR_GREATER,
216 
217 		VERIFICATION_TYPE_UNDEFINED
218 	};
219 
220 	/* Code of a compute shader used by a functional test that verifies
221 	 * GL_COMPUTE_SHADER_INVOCATIONS_ARB query works correctly.
222 	 */
223 	static const char* minimal_cs_code;
224 	static const char* minimal_cs_code_arb;
225 	/* Code of a fragment shader used by a number of functional tests */
226 	static const char* minimal_fs_code;
227 	/* Code of a tessellation control shader used by a functional test that verifies
228 	 * GL_TESS_CONTROL_SHADER_PATCHES_ARB and GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB
229 	 * queries work correctly.
230 	 */
231 	static const char* minimal_tc_code;
232 	/* Code of a tessellation evaluation shader used by a functional test that verifies
233 	 * GL_TESS_CONTROL_SHADER_PATCHES_ARB and GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB
234 	 * queries work correctly.
235 	 */
236 	static const char* minimal_te_code;
237 	/* Code of a vertex shader used by a number of functional tests */
238 	static const char* minimal_vs_code;
239 
240 	/* Tells how many query targets are stored in query_targets */
241 	static const unsigned int n_query_targets;
242 	/* Stores all query targets that should be used by the tests */
243 	static const glw::GLenum query_targets[];
244 
245 	/* Tells the offset, relative to the beginning of the buffer object storage,
246 	 * from which the query's int32 result value starts. */
247 	static const unsigned int qo_bo_int_offset;
248 	/* Tells the offset, relative to the beginning of the buffer object storage,
249 	 * from which the query's int64 result value starts. */
250 	static const unsigned int qo_bo_int64_offset;
251 	/* Tells the offset, relative to the beginning of the buffer object storage,
252 	 * from which the query's uint32 result value starts. */
253 	static const unsigned int qo_bo_uint_offset;
254 	/* Tells the offset, relative to the beginning of the buffer object storage,
255 	 * from which the query's uint64 result value starts. */
256 	static const unsigned int qo_bo_uint64_offset;
257 	static const unsigned int qo_bo_size;
258 
259 	/* Public methods */
260 	static std::string buildGeometryShaderBody(_geometry_shader_input gs_input, _geometry_shader_output gs_output,
261 											   unsigned int n_primitives_to_emit_in_stream0, unsigned int n_streams);
262 
263 	static bool executeQuery(glw::GLenum query_type, glw::GLuint qo_id, glw::GLuint qo_bo_id,
264 							 PFNQUERYDRAWHANDLERPROC pfn_draw, void* draw_user_arg,
265 							 const glu::RenderContext& render_context, tcu::TestContext& test_context,
266 							 const glu::ContextInfo& context_info, _test_execution_result* out_result,
267 							 bool& skipped);
268 
269 	static glw::GLenum getEnumForPrimitiveType(_primitive_type primitive_type);
270 	static std::string getGLSLStringForGSInput(_geometry_shader_input gs_input);
271 	static std::string getGLSLStringForGSOutput(_geometry_shader_output gs_output);
272 	static unsigned int getNumberOfVerticesForGSInput(_geometry_shader_input gs_input);
273 	static unsigned int getNumberOfVerticesForGSOutput(_geometry_shader_output gs_output);
274 	static unsigned int getNumberOfVerticesForPrimitiveType(_primitive_type primitive_type);
275 	static _primitive_type getPrimitiveTypeFromGSInput(_geometry_shader_input gs_input);
276 	static std::string getStringForDrawCallType(_draw_call_type draw_call_type);
277 	static std::string getStringForEnum(glw::GLenum value);
278 	static std::string getStringForPrimitiveType(_primitive_type primitive_type);
279 
280 	static bool isDrawCallSupported(_draw_call_type draw_call, const glw::Functions& gl);
281 
282 	static bool isInstancedDrawCall(_draw_call_type draw_call);
283 
284 	static bool isQuerySupported(glw::GLenum value, const glu::ContextInfo& context_info,
285 								 const glu::RenderContext& render_context);
286 
287 	static bool verifyResultValues(const _test_execution_result& run_result, unsigned int n_expected_values,
288 								   const glw::GLuint64* expected_values, bool should_check_qo_bo_values,
289 								   const glw::GLenum query_type, const _draw_call_type* draw_call_type_ptr,
290 								   const _primitive_type* primitive_type_ptr, bool is_primitive_restart_enabled,
291 								   tcu::TestContext& test_context, _verification_type verification_type);
292 
293 	/** Constructs a string that describes details of a test iteration that has been
294 	 *  detected to have failed.
295 	 *
296 	 *  @param value                        Query counter value as retrieved by the test iteration.
297 	 *  @param value_type                   Null-terminated string holding the name of the type
298 	 *                                      of the result value.
299 	 *  @param n_expected_values            Number of possible expected values.
300 	 *  @param expected_values              Array of possible expected values.
301 	 *  @param query_type                   Type of the query used by the test iteration.
302 	 *  @param draw_call_type_name          Type of the draw call used by the test iteration.
303 	 *  @param primitive_type_name          Primitive type used for the test iteration's draw call.
304 	 *  @param is_primitive_restart_enabled true if the test iteration was run with "primitive restart"
305 	 *                                      functionality enabled, false otherwise.
306 	 *
307 	 *  @return                             String that includes a human-readable description of the
308 	 *                                      test iteration's properties.
309 	 *
310 	 */
311 	template <typename VALUE_TYPE>
getVerifyResultValuesErrorString(VALUE_TYPE value,const char * value_type,unsigned int n_expected_values,const glw::GLuint64 * expected_values,glw::GLenum query_type,std::string draw_call_type_name,std::string primitive_type_name,bool is_primitive_restart_enabled)312 	static std::string getVerifyResultValuesErrorString(VALUE_TYPE value, const char* value_type,
313 														unsigned int		 n_expected_values,
314 														const glw::GLuint64* expected_values, glw::GLenum query_type,
315 														std::string draw_call_type_name,
316 														std::string primitive_type_name,
317 														bool		is_primitive_restart_enabled)
318 	{
319 		std::stringstream log_sstream;
320 
321 		DE_ASSERT(expected_values != DE_NULL);
322 
323 		log_sstream << "Invalid default " << value_type << " query result value: found "
324 														   "["
325 					<< value << "], expected:"
326 								"["
327 					<< expected_values[0] << "]";
328 
329 		for (unsigned int i = 1; i < n_expected_values; ++i)
330 		{
331 			log_sstream << " or [" << expected_values[i] << "]";
332 		}
333 
334 		log_sstream << ", query type:"
335 					   "["
336 					<< getStringForEnum(query_type) << "], "
337 													   "GL_PRIMITIVE_RESTART mode:"
338 													   "["
339 					<< ((is_primitive_restart_enabled) ? "enabled" : "disabled") << "]"
340 																					", draw call type:"
341 																					"["
342 					<< draw_call_type_name.c_str() << "]"
343 													  ", primitive type:"
344 													  "["
345 					<< primitive_type_name.c_str() << "].";
346 
347 		return log_sstream.str();
348 	}
349 };
350 
351 /** Check that calling BeginQuery with a pipeline statistics query target
352  *  generates an INVALID_OPERATION error if the specified query was
353  *  previously used with a different pipeline statistics query target.
354  **/
355 class PipelineStatisticsQueryTestAPICoverage1 : public deqp::TestCase
356 {
357 public:
358 	/* Public methods */
359 	PipelineStatisticsQueryTestAPICoverage1(deqp::Context& context);
360 
361 	virtual void						 deinit();
362 	virtual tcu::TestNode::IterateResult iterate();
363 
364 private:
365 	/* Private fields */
366 	glw::GLuint m_qo_id;
367 };
368 
369 /** Performs the following tests:
370  *
371  *  * If GL 3.2 and ARB_geometry_shader4 are not supported then check that
372  *    calling BeginQuery with target GEOMETRY_SHADER_INVOCATIONS or
373  *    GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB generates an INVALID_ENUM error.
374  *
375  *  * If GL 4.0 and ARB_tessellation_shader are not supported then check that
376  *    calling BeginQuery with target TESS_CONTROL_SHADER_INVOCATIONS_ARB or
377  *    TESS_EVALUATION_SHADER_INVOCATIONS_ARB generates an INVALID_ENUM error.
378  *
379  *  * If GL 4.3 and ARB_compute_shader are not supported then check that
380  *    calling BeginQuery with target COMPUTE_SHADER_INVOCATIONS_ARB generates
381  *    an INVALID_ENUM error.
382  *
383  **/
384 class PipelineStatisticsQueryTestAPICoverage2 : public deqp::TestCase
385 {
386 public:
387 	/* Public methods */
388 	PipelineStatisticsQueryTestAPICoverage2(deqp::Context& context);
389 
390 	virtual void						 deinit();
391 	virtual tcu::TestNode::IterateResult iterate();
392 
393 private:
394 	/* Private fields */
395 	glw::GLuint m_qo_id;
396 };
397 
398 /** Base class used by all functional test implementations. Provides various
399  *  methods that are shared between functional tests.
400  *
401  *  Derivative classes must implement executeTest() method.
402  */
403 class PipelineStatisticsQueryTestFunctionalBase : public deqp::TestCase
404 {
405 public:
406 	/* Public methods */
407 	PipelineStatisticsQueryTestFunctionalBase(deqp::Context& context, const char* name, const char* description);
408 
409 	virtual void						 deinit();
410 	virtual tcu::TestNode::IterateResult iterate();
411 
412 protected:
413 	/* Protected methods */
414 	void buildProgram(const char* cs_body, const char* fs_body, const char* gs_body, const char* tc_body,
415 					  const char* te_body, const char* vs_body);
416 
417 	virtual void deinitObjects();
418 
419 	virtual bool executeTest(glw::GLenum current_query_target) = 0;
420 	void		 initFBO();
421 	virtual void initObjects();
422 	void		 initQOBO();
423 	void initVAO(unsigned int n_components_per_vertex);
424 
425 	void initVBO(const float* raw_vertex_data, unsigned int raw_vertex_data_size, const unsigned int* raw_index_data,
426 				 unsigned int raw_index_data_size, unsigned int indirect_draw_bo_count_argument,
427 				 unsigned int indirect_draw_bo_primcount_argument, unsigned int indirect_draw_bo_baseinstance_argument,
428 				 unsigned int indirect_draw_bo_first_argument,		 /* glDrawArrays() only */
429 				 unsigned int indirect_draw_bo_basevertex_argument); /* glDrawElements() only */
430 
431 	virtual bool shouldExecuteForQueryTarget(glw::GLenum query_target);
432 
433 	/* Protected static methods */
434 	static bool queryCallbackDrawCallHandler(void* pThis);
435 
436 	/* Protected fields */
437 	glw::GLuint m_bo_qo_id;
438 	glw::GLuint m_fbo_id;
439 	glw::GLuint m_po_id;
440 	glw::GLuint m_qo_id;
441 	glw::GLuint m_to_id;
442 	glw::GLuint m_vao_id;
443 	glw::GLuint m_vbo_id;
444 
445 	const unsigned int m_to_height;
446 	const unsigned int m_to_width;
447 
448 	unsigned int m_vbo_indirect_arrays_argument_offset;
449 	unsigned int m_vbo_indirect_elements_argument_offset;
450 	unsigned int m_vbo_index_data_offset;
451 	unsigned int m_vbo_n_indices;
452 	unsigned int m_vbo_vertex_data_offset;
453 
454 	PipelineStatisticsQueryUtilities::_draw_call_type m_current_draw_call_type;
455 	PipelineStatisticsQueryUtilities::_primitive_type m_current_primitive_type;
456 	unsigned int									  m_indirect_draw_call_baseinstance_argument;
457 	unsigned int									  m_indirect_draw_call_basevertex_argument;
458 	unsigned int									  m_indirect_draw_call_count_argument;
459 	unsigned int									  m_indirect_draw_call_first_argument;
460 	unsigned int									  m_indirect_draw_call_firstindex_argument;
461 	unsigned int									  m_indirect_draw_call_primcount_argument;
462 };
463 
464 /** Performs the following functional test:
465  *
466  * Check that all pipeline statistics query types return a result of zero
467  * if no rendering commands are issued between BeginQuery and EndQuery.
468  *
469  **/
470 class PipelineStatisticsQueryTestFunctional1 : public PipelineStatisticsQueryTestFunctionalBase
471 {
472 public:
473 	/* Public methods */
474 	PipelineStatisticsQueryTestFunctional1(deqp::Context& context);
475 
476 protected:
477 	/* Protected methods */
478 	bool executeTest(glw::GLenum current_query_target);
479 };
480 
481 /** Performs the following functional test:
482  *
483  * Check that all pipeline statistics query types return a result of zero
484  * if Clear, ClearBuffer*, BlitFramebuffer, or any of the non-rendering
485  * commands involving blits or copies (e.g. TexSubImage, CopyImageSubData,
486  * ClearTexSubImage, BufferSubData, ClearBufferSubData) are issued between
487  * BeginQuery and EndQuery.
488  *
489  **/
490 class PipelineStatisticsQueryTestFunctional2 : public PipelineStatisticsQueryTestFunctionalBase
491 {
492 public:
493 	/* Public methods */
494 	PipelineStatisticsQueryTestFunctional2(deqp::Context& context);
495 
496 protected:
497 	/* Protected methods */
498 	void deinitObjects();
499 	bool executeTest(glw::GLenum current_query_target);
500 	void initObjects();
501 
502 private:
503 	static bool executeBlitFramebufferTest(void* pThis);
504 	static bool executeBufferSubDataTest(void* pThis);
505 	static bool executeClearBufferfvColorBufferTest(void* pThis);
506 	static bool executeClearBufferfvDepthBufferTest(void* pThis);
507 	static bool executeClearBufferivStencilBufferTest(void* pThis);
508 	static bool executeClearBufferSubDataTest(void* pThis);
509 	static bool executeClearColorBufferTest(void* pThis);
510 	static bool executeClearDepthBufferTest(void* pThis);
511 	static bool executeClearStencilBufferTest(void* pThis);
512 	static bool executeClearTexSubImageTest(void* pThis);
513 	static bool executeCopyImageSubDataTest(void* pThis);
514 	static bool executeTexSubImageTest(void* pThis);
515 
516 	/* Private fields */
517 	glw::GLuint m_bo_id;
518 	glw::GLuint m_fbo_draw_id;
519 	glw::GLuint m_fbo_read_id;
520 	glw::GLuint m_to_draw_fbo_id;
521 	glw::GLuint m_to_read_fbo_id;
522 
523 	const glw::GLuint m_to_height;
524 	const glw::GLuint m_to_width;
525 
526 	static const glw::GLuint bo_size;
527 };
528 
529 /** Performs the following functional tests:
530  *
531  * Using the basic outline check that VERTICES_SUBMITTED_ARB queries return
532  * the number of vertices submitted using draw commands. Vertices
533  * corresponding to partial/incomplete primitives may or may not be counted
534  * (e.g. when submitting a single instance with 8 vertices with primitive
535  * mode TRIANGLES, the result of the query could be either 6 or 8).
536  *
537  * Using the basic outline check that VERTICES_SUBMITTED_ARB queries don't
538  * count primitive topology restarts when PRIMITIVE_RESTART is enabled and
539  * DrawElements* is used to submit an element array which contains one or
540  * more primitive restart index values.
541  *
542  * Using the basic outline check that PRIMITIVES_SUBMITTED_ARB queries
543  * return the exact number of primitives submitted using draw commands.
544  * Partial/incomplete primitives may or may not be counted (e.g. when
545  * submitting a single instance with 8 vertices with primitive mode
546  * TRIANGLES, the result of the query could be either 2 or 3). Test the
547  * behavior with all supported primitive modes.
548  *
549  * Using the basic outline check that PRIMITIVES_SUBMITTED_ARB queries
550  * don't count primitive topology restarts when PRIMITIVE_RESTART is
551  * enabled and DrawElements* is used to submit an element array which
552  * contains one or more primitive restart index values. Also, partial/
553  * incomplete primitives resulting from the use of primitive restart index
554  * values may or may not be counted.
555  *
556  * Using the basic outline check that CLIPPING_INPUT_PRIMITIVES_ARB queries
557  * return the exact number of primitives reaching the primitive clipping
558  * stage. If RASTERIZER_DISCARD is disabled, and the tessellation and
559  * geometry shader stage is not used, this should match the number of
560  * primitives submitted.
561  *
562  * Using the basic outline check that CLIPPING_OUTPUT_PRIMITIVES_ARB
563  * queries return a value that is always greater than or equal to the
564  * number of primitives submitted if RASTERIZER_DISCARD is disabled, there
565  * is no tessellation and geometry shader stage used, and all primitives
566  * lie entirely in the cull volume.
567  *
568  **/
569 class PipelineStatisticsQueryTestFunctional3 : public PipelineStatisticsQueryTestFunctionalBase
570 {
571 public:
572 	/* Public methods */
573 	PipelineStatisticsQueryTestFunctional3(deqp::Context& context);
574 
575 protected:
576 	/* Protected methods */
577 	void deinitObjects();
578 	bool executeTest(glw::GLenum current_query_target);
579 	void initObjects();
580 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
581 
582 private:
583 	/* Private methods */
584 	void getExpectedPrimitivesSubmittedQueryResult(
585 		PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type, unsigned int* out_results_written,
586 		glw::GLuint64 out_results[4]);
587 
588 	void getExpectedVerticesSubmittedQueryResult(
589 		PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type, unsigned int* out_results_written,
590 		glw::GLuint64 out_results[4]);
591 
592 	/* Private fields */
593 	bool m_is_primitive_restart_enabled;
594 };
595 
596 /** Performs the following functional test:
597  *
598  * Using the basic outline with a program having a vertex shader check that
599  * VERTEX_SHADER_INVOCATIONS_ARB queries return a result greater than zero
600  * if at least one vertex is submitted to the GL.
601  *
602  **/
603 class PipelineStatisticsQueryTestFunctional4 : public PipelineStatisticsQueryTestFunctionalBase
604 {
605 public:
606 	/* Public methods */
607 	PipelineStatisticsQueryTestFunctional4(deqp::Context& context);
608 
609 protected:
610 	/* Protected methods */
611 	void deinitObjects();
612 	bool executeTest(glw::GLenum current_query_target);
613 	void initObjects();
614 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
615 };
616 
617 /** Performs the following functional test:
618  *
619  * If GL 4.0 is supported, using the basic outline with a program having a
620  * tessellation control and tessellation evaluation shader check that
621  * TESS_CONTROL_SHADER_INVOCATIONS_ARB and TESS_EVALUATION_SHADER_-
622  * INVOCATIONS_ARB queries return a result greater than zero if at least
623  * one patch is needed to be processed by the GL (e.g. PATCH_VERTICES is 3,
624  * and at least 3 vertices are submitted to the GL).
625  *
626  **/
627 class PipelineStatisticsQueryTestFunctional5 : public PipelineStatisticsQueryTestFunctionalBase
628 {
629 public:
630 	/* Public methods */
631 	PipelineStatisticsQueryTestFunctional5(deqp::Context& context);
632 
633 protected:
634 	/* Protected methods */
635 	void deinitObjects();
636 	bool executeTest(glw::GLenum current_query_target);
637 	void initObjects();
638 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
639 };
640 
641 /** Performs the following functional test:
642  *
643  * If GL 3.2 is supported, using the basic outline with a program having a
644  * geometry shader check that GEOMETRY_SHADER_INVOCATIONS queries return
645  * a result greater than zero if at least one complete primitive is
646  * submitted to the GL.
647  *
648  * If GL 3.2 is supported, using the basic outline with a program having a
649  * geometry shader check that GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB
650  * queries return the exact number of primitives emitted by the geometry
651  * shader. Also, if GL 4.0 is supported, use a geometry shader that emits
652  * primitives to multiple vertex streams. In this case the result of
653  * GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB has to match the sum of the
654  * number of primitives emitted to each particular vertex stream.
655  *
656  **/
657 class PipelineStatisticsQueryTestFunctional6 : public PipelineStatisticsQueryTestFunctionalBase
658 {
659 public:
660 	/* Public methods */
661 	PipelineStatisticsQueryTestFunctional6(deqp::Context& context);
662 
663 protected:
664 	/* Protected methods */
665 	void deinitObjects();
666 	bool executeTest(glw::GLenum current_query_target);
667 	void initObjects();
668 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
669 
670 private:
671 	/* Private fields */
672 	const unsigned int m_n_primitives_emitted_by_gs;
673 	const unsigned int m_n_streams_emitted_by_gs;
674 };
675 
676 /** Performs the following functional test:
677  *
678  * Using the basic outline with a program having a fragment shader check
679  * that FRAGMENT_SHADER_INVOCATIONS_ARB queries return a result greater
680  * than zero if at least one fragment gets rasterized.
681  *
682  **/
683 class PipelineStatisticsQueryTestFunctional7 : public PipelineStatisticsQueryTestFunctionalBase
684 {
685 public:
686 	/* Public methods */
687 	PipelineStatisticsQueryTestFunctional7(deqp::Context& context);
688 
689 protected:
690 	/* Protected methods */
691 	void deinitObjects();
692 	bool executeTest(glw::GLenum current_query_target);
693 	void initObjects();
694 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
695 };
696 
697 /** Performs the following functional test:
698  *
699  * Using the basic outline with a program having a compute shader check
700  * that COMPUTE_SHADER_INVOCATIONS_ARB queries return a result greater
701  * than zero if at least a single work group is submitted using one of the
702  * Dispatch* commands.
703  *
704  **/
705 class PipelineStatisticsQueryTestFunctional8 : public PipelineStatisticsQueryTestFunctionalBase
706 {
707 public:
708 	/* Public methods */
709 	PipelineStatisticsQueryTestFunctional8(deqp::Context& context);
710 
711 protected:
712 	/* Protected methods */
713 	void deinitObjects();
714 	bool executeTest(glw::GLenum current_query_target);
715 	void initObjects();
716 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
717 
718 private:
719 	/* Private methods */
720 	static bool queryCallbackDispatchCallHandler(void* pInstance);
721 
722 	/* Private fields */
723 	glw::GLuint  m_bo_dispatch_compute_indirect_args_offset;
724 	glw::GLuint  m_bo_id;
725 	unsigned int m_current_iteration;
726 };
727 
728 /** Test group which encapsulates all conformance tests for
729  *  GL_ARB_pipeline_statistics_query extension.
730  */
731 class PipelineStatisticsQueryTests : public deqp::TestCaseGroup
732 {
733 public:
734 	/* Public methods */
735 	PipelineStatisticsQueryTests(deqp::Context& context);
736 
737 	void init(void);
738 
739 private:
740 	PipelineStatisticsQueryTests(const PipelineStatisticsQueryTests& other);
741 	PipelineStatisticsQueryTests& operator=(const PipelineStatisticsQueryTests& other);
742 };
743 
744 } /* glcts namespace */
745 
746 #endif // _GL4CPIPELINESTATISTICSQUERYTESTS_HPP
747