• 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* dummy_cs_code;
224 	static const char* dummy_cs_code_arb;
225 	/* Code of a fragment shader used by a number of functional tests */
226 	static const char* dummy_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* dummy_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* dummy_te_code;
237 	/* Code of a vertex shader used by a number of functional tests */
238 	static const char* dummy_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 
268 	static glw::GLenum getEnumForPrimitiveType(_primitive_type primitive_type);
269 	static std::string getGLSLStringForGSInput(_geometry_shader_input gs_input);
270 	static std::string getGLSLStringForGSOutput(_geometry_shader_output gs_output);
271 	static unsigned int getNumberOfVerticesForGSInput(_geometry_shader_input gs_input);
272 	static unsigned int getNumberOfVerticesForGSOutput(_geometry_shader_output gs_output);
273 	static unsigned int getNumberOfVerticesForPrimitiveType(_primitive_type primitive_type);
274 	static _primitive_type getPrimitiveTypeFromGSInput(_geometry_shader_input gs_input);
275 	static std::string getStringForDrawCallType(_draw_call_type draw_call_type);
276 	static std::string getStringForEnum(glw::GLenum value);
277 	static std::string getStringForPrimitiveType(_primitive_type primitive_type);
278 
279 	static bool isDrawCallSupported(_draw_call_type draw_call, const glw::Functions& gl);
280 
281 	static bool isInstancedDrawCall(_draw_call_type draw_call);
282 
283 	static bool isQuerySupported(glw::GLenum value, const glu::ContextInfo& context_info,
284 								 const glu::RenderContext& render_context);
285 
286 	static bool verifyResultValues(const _test_execution_result& run_result, unsigned int n_expected_values,
287 								   const glw::GLuint64* expected_values, bool should_check_qo_bo_values,
288 								   const glw::GLenum query_type, const _draw_call_type* draw_call_type_ptr,
289 								   const _primitive_type* primitive_type_ptr, bool is_primitive_restart_enabled,
290 								   tcu::TestContext& test_context, _verification_type verification_type);
291 
292 	/** Constructs a string that describes details of a test iteration that has been
293 	 *  detected to have failed.
294 	 *
295 	 *  @param value                        Query counter value as retrieved by the test iteration.
296 	 *  @param value_type                   Null-terminated string holding the name of the type
297 	 *                                      of the result value.
298 	 *  @param n_expected_values            Number of possible expected values.
299 	 *  @param expected_values              Array of possible expected values.
300 	 *  @param query_type                   Type of the query used by the test iteration.
301 	 *  @param draw_call_type_name          Type of the draw call used by the test iteration.
302 	 *  @param primitive_type_name          Primitive type used for the test iteration's draw call.
303 	 *  @param is_primitive_restart_enabled true if the test iteration was run with "primitive restart"
304 	 *                                      functionality enabled, false otherwise.
305 	 *
306 	 *  @return                             String that includes a human-readable description of the
307 	 *                                      test iteration's properties.
308 	 *
309 	 */
310 	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)311 	static std::string getVerifyResultValuesErrorString(VALUE_TYPE value, const char* value_type,
312 														unsigned int		 n_expected_values,
313 														const glw::GLuint64* expected_values, glw::GLenum query_type,
314 														std::string draw_call_type_name,
315 														std::string primitive_type_name,
316 														bool		is_primitive_restart_enabled)
317 	{
318 		std::stringstream log_sstream;
319 
320 		DE_ASSERT(expected_values != DE_NULL);
321 
322 		log_sstream << "Invalid default " << value_type << " query result value: found "
323 														   "["
324 					<< value << "], expected:"
325 								"["
326 					<< expected_values[0] << "]";
327 
328 		for (unsigned int i = 1; i < n_expected_values; ++i)
329 		{
330 			log_sstream << " or [" << expected_values[i] << "]";
331 		}
332 
333 		log_sstream << ", query type:"
334 					   "["
335 					<< getStringForEnum(query_type) << "], "
336 													   "GL_PRIMITIVE_RESTART mode:"
337 													   "["
338 					<< ((is_primitive_restart_enabled) ? "enabled" : "disabled") << "]"
339 																					", draw call type:"
340 																					"["
341 					<< draw_call_type_name.c_str() << "]"
342 													  ", primitive type:"
343 													  "["
344 					<< primitive_type_name.c_str() << "].";
345 
346 		return log_sstream.str();
347 	}
348 };
349 
350 /** Check that calling BeginQuery with a pipeline statistics query target
351  *  generates an INVALID_OPERATION error if the specified query was
352  *  previously used with a different pipeline statistics query target.
353  **/
354 class PipelineStatisticsQueryTestAPICoverage1 : public deqp::TestCase
355 {
356 public:
357 	/* Public methods */
358 	PipelineStatisticsQueryTestAPICoverage1(deqp::Context& context);
359 
360 	virtual void						 deinit();
361 	virtual tcu::TestNode::IterateResult iterate();
362 
363 private:
364 	/* Private fields */
365 	glw::GLuint m_qo_id;
366 };
367 
368 /** Performs the following tests:
369  *
370  *  * If GL 3.2 and ARB_geometry_shader4 are not supported then check that
371  *    calling BeginQuery with target GEOMETRY_SHADER_INVOCATIONS or
372  *    GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB generates an INVALID_ENUM error.
373  *
374  *  * If GL 4.0 and ARB_tessellation_shader are not supported then check that
375  *    calling BeginQuery with target TESS_CONTROL_SHADER_INVOCATIONS_ARB or
376  *    TESS_EVALUATION_SHADER_INVOCATIONS_ARB generates an INVALID_ENUM error.
377  *
378  *  * If GL 4.3 and ARB_compute_shader are not supported then check that
379  *    calling BeginQuery with target COMPUTE_SHADER_INVOCATIONS_ARB generates
380  *    an INVALID_ENUM error.
381  *
382  **/
383 class PipelineStatisticsQueryTestAPICoverage2 : public deqp::TestCase
384 {
385 public:
386 	/* Public methods */
387 	PipelineStatisticsQueryTestAPICoverage2(deqp::Context& context);
388 
389 	virtual void						 deinit();
390 	virtual tcu::TestNode::IterateResult iterate();
391 
392 private:
393 	/* Private fields */
394 	glw::GLuint m_qo_id;
395 };
396 
397 /** Base class used by all functional test implementations. Provides various
398  *  methods that are shared between functional tests.
399  *
400  *  Derivative classes must implement executeTest() method.
401  */
402 class PipelineStatisticsQueryTestFunctionalBase : public deqp::TestCase
403 {
404 public:
405 	/* Public methods */
406 	PipelineStatisticsQueryTestFunctionalBase(deqp::Context& context, const char* name, const char* description);
407 
408 	virtual void						 deinit();
409 	virtual tcu::TestNode::IterateResult iterate();
410 
411 protected:
412 	/* Protected methods */
413 	void buildProgram(const char* cs_body, const char* fs_body, const char* gs_body, const char* tc_body,
414 					  const char* te_body, const char* vs_body);
415 
416 	virtual void deinitObjects();
417 
418 	virtual bool executeTest(glw::GLenum current_query_target) = 0;
419 	void		 initFBO();
420 	virtual void initObjects();
421 	void		 initQOBO();
422 	void initVAO(unsigned int n_components_per_vertex);
423 
424 	void initVBO(const float* raw_vertex_data, unsigned int raw_vertex_data_size, const unsigned int* raw_index_data,
425 				 unsigned int raw_index_data_size, unsigned int indirect_draw_bo_count_argument,
426 				 unsigned int indirect_draw_bo_primcount_argument, unsigned int indirect_draw_bo_baseinstance_argument,
427 				 unsigned int indirect_draw_bo_first_argument,		 /* glDrawArrays() only */
428 				 unsigned int indirect_draw_bo_basevertex_argument); /* glDrawElements() only */
429 
430 	virtual bool shouldExecuteForQueryTarget(glw::GLenum query_target);
431 
432 	/* Protected static methods */
433 	static bool queryCallbackDrawCallHandler(void* pThis);
434 
435 	/* Protected fields */
436 	glw::GLuint m_bo_qo_id;
437 	glw::GLuint m_fbo_id;
438 	glw::GLuint m_po_id;
439 	glw::GLuint m_qo_id;
440 	glw::GLuint m_to_id;
441 	glw::GLuint m_vao_id;
442 	glw::GLuint m_vbo_id;
443 
444 	const unsigned int m_to_height;
445 	const unsigned int m_to_width;
446 
447 	unsigned int m_vbo_indirect_arrays_argument_offset;
448 	unsigned int m_vbo_indirect_elements_argument_offset;
449 	unsigned int m_vbo_index_data_offset;
450 	unsigned int m_vbo_n_indices;
451 	unsigned int m_vbo_vertex_data_offset;
452 
453 	PipelineStatisticsQueryUtilities::_draw_call_type m_current_draw_call_type;
454 	PipelineStatisticsQueryUtilities::_primitive_type m_current_primitive_type;
455 	unsigned int									  m_indirect_draw_call_baseinstance_argument;
456 	unsigned int									  m_indirect_draw_call_basevertex_argument;
457 	unsigned int									  m_indirect_draw_call_count_argument;
458 	unsigned int									  m_indirect_draw_call_first_argument;
459 	unsigned int									  m_indirect_draw_call_firstindex_argument;
460 	unsigned int									  m_indirect_draw_call_primcount_argument;
461 };
462 
463 /** Performs the following functional test:
464  *
465  * Check that all pipeline statistics query types return a result of zero
466  * if no rendering commands are issued between BeginQuery and EndQuery.
467  *
468  **/
469 class PipelineStatisticsQueryTestFunctional1 : public PipelineStatisticsQueryTestFunctionalBase
470 {
471 public:
472 	/* Public methods */
473 	PipelineStatisticsQueryTestFunctional1(deqp::Context& context);
474 
475 protected:
476 	/* Protected methods */
477 	bool executeTest(glw::GLenum current_query_target);
478 };
479 
480 /** Performs the following functional test:
481  *
482  * Check that all pipeline statistics query types return a result of zero
483  * if Clear, ClearBuffer*, BlitFramebuffer, or any of the non-rendering
484  * commands involving blits or copies (e.g. TexSubImage, CopyImageSubData,
485  * ClearTexSubImage, BufferSubData, ClearBufferSubData) are issued between
486  * BeginQuery and EndQuery.
487  *
488  **/
489 class PipelineStatisticsQueryTestFunctional2 : public PipelineStatisticsQueryTestFunctionalBase
490 {
491 public:
492 	/* Public methods */
493 	PipelineStatisticsQueryTestFunctional2(deqp::Context& context);
494 
495 protected:
496 	/* Protected methods */
497 	void deinitObjects();
498 	bool executeTest(glw::GLenum current_query_target);
499 	void initObjects();
500 
501 private:
502 	static bool executeBlitFramebufferTest(void* pThis);
503 	static bool executeBufferSubDataTest(void* pThis);
504 	static bool executeClearBufferfvColorBufferTest(void* pThis);
505 	static bool executeClearBufferfvDepthBufferTest(void* pThis);
506 	static bool executeClearBufferivStencilBufferTest(void* pThis);
507 	static bool executeClearBufferSubDataTest(void* pThis);
508 	static bool executeClearColorBufferTest(void* pThis);
509 	static bool executeClearDepthBufferTest(void* pThis);
510 	static bool executeClearStencilBufferTest(void* pThis);
511 	static bool executeClearTexSubImageTest(void* pThis);
512 	static bool executeCopyImageSubDataTest(void* pThis);
513 	static bool executeTexSubImageTest(void* pThis);
514 
515 	/* Private fields */
516 	glw::GLuint m_bo_id;
517 	glw::GLuint m_fbo_draw_id;
518 	glw::GLuint m_fbo_read_id;
519 	glw::GLuint m_to_draw_fbo_id;
520 	glw::GLuint m_to_read_fbo_id;
521 
522 	const glw::GLuint m_to_height;
523 	const glw::GLuint m_to_width;
524 
525 	static const glw::GLuint bo_size;
526 };
527 
528 /** Performs the following functional tests:
529  *
530  * Using the basic outline check that VERTICES_SUBMITTED_ARB queries return
531  * the number of vertices submitted using draw commands. Vertices
532  * corresponding to partial/incomplete primitives may or may not be counted
533  * (e.g. when submitting a single instance with 8 vertices with primitive
534  * mode TRIANGLES, the result of the query could be either 6 or 8).
535  *
536  * Using the basic outline check that VERTICES_SUBMITTED_ARB queries don't
537  * count primitive topology restarts when PRIMITIVE_RESTART is enabled and
538  * DrawElements* is used to submit an element array which contains one or
539  * more primitive restart index values.
540  *
541  * Using the basic outline check that PRIMITIVES_SUBMITTED_ARB queries
542  * return the exact number of primitives submitted using draw commands.
543  * Partial/incomplete primitives may or may not be counted (e.g. when
544  * submitting a single instance with 8 vertices with primitive mode
545  * TRIANGLES, the result of the query could be either 2 or 3). Test the
546  * behavior with all supported primitive modes.
547  *
548  * Using the basic outline check that PRIMITIVES_SUBMITTED_ARB queries
549  * don't count primitive topology restarts when PRIMITIVE_RESTART is
550  * enabled and DrawElements* is used to submit an element array which
551  * contains one or more primitive restart index values. Also, partial/
552  * incomplete primitives resulting from the use of primitive restart index
553  * values may or may not be counted.
554  *
555  * Using the basic outline check that CLIPPING_INPUT_PRIMITIVES_ARB queries
556  * return the exact number of primitives reaching the primitive clipping
557  * stage. If RASTERIZER_DISCARD is disabled, and the tessellation and
558  * geometry shader stage is not used, this should match the number of
559  * primitives submitted.
560  *
561  * Using the basic outline check that CLIPPING_OUTPUT_PRIMITIVES_ARB
562  * queries return a value that is always greater than or equal to the
563  * number of primitives submitted if RASTERIZER_DISCARD is disabled, there
564  * is no tessellation and geometry shader stage used, and all primitives
565  * lie entirely in the cull volume.
566  *
567  **/
568 class PipelineStatisticsQueryTestFunctional3 : public PipelineStatisticsQueryTestFunctionalBase
569 {
570 public:
571 	/* Public methods */
572 	PipelineStatisticsQueryTestFunctional3(deqp::Context& context);
573 
574 protected:
575 	/* Protected methods */
576 	void deinitObjects();
577 	bool executeTest(glw::GLenum current_query_target);
578 	void initObjects();
579 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
580 
581 private:
582 	/* Private methods */
583 	void getExpectedPrimitivesSubmittedQueryResult(
584 		PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type, unsigned int* out_results_written,
585 		glw::GLuint64 out_results[4]);
586 
587 	void getExpectedVerticesSubmittedQueryResult(
588 		PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type, unsigned int* out_results_written,
589 		glw::GLuint64 out_results[4]);
590 
591 	/* Private fields */
592 	bool m_is_primitive_restart_enabled;
593 };
594 
595 /** Performs the following functional test:
596  *
597  * Using the basic outline with a program having a vertex shader check that
598  * VERTEX_SHADER_INVOCATIONS_ARB queries return a result greater than zero
599  * if at least one vertex is submitted to the GL.
600  *
601  **/
602 class PipelineStatisticsQueryTestFunctional4 : public PipelineStatisticsQueryTestFunctionalBase
603 {
604 public:
605 	/* Public methods */
606 	PipelineStatisticsQueryTestFunctional4(deqp::Context& context);
607 
608 protected:
609 	/* Protected methods */
610 	void deinitObjects();
611 	bool executeTest(glw::GLenum current_query_target);
612 	void initObjects();
613 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
614 };
615 
616 /** Performs the following functional test:
617  *
618  * If GL 4.0 is supported, using the basic outline with a program having a
619  * tessellation control and tessellation evaluation shader check that
620  * TESS_CONTROL_SHADER_INVOCATIONS_ARB and TESS_EVALUATION_SHADER_-
621  * INVOCATIONS_ARB queries return a result greater than zero if at least
622  * one patch is needed to be processed by the GL (e.g. PATCH_VERTICES is 3,
623  * and at least 3 vertices are submitted to the GL).
624  *
625  **/
626 class PipelineStatisticsQueryTestFunctional5 : public PipelineStatisticsQueryTestFunctionalBase
627 {
628 public:
629 	/* Public methods */
630 	PipelineStatisticsQueryTestFunctional5(deqp::Context& context);
631 
632 protected:
633 	/* Protected methods */
634 	void deinitObjects();
635 	bool executeTest(glw::GLenum current_query_target);
636 	void initObjects();
637 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
638 };
639 
640 /** Performs the following functional test:
641  *
642  * If GL 3.2 is supported, using the basic outline with a program having a
643  * geometry shader check that GEOMETRY_SHADER_INVOCATIONS queries return
644  * a result greater than zero if at least one complete primitive is
645  * submitted to the GL.
646  *
647  * If GL 3.2 is supported, using the basic outline with a program having a
648  * geometry shader check that GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB
649  * queries return the exact number of primitives emitted by the geometry
650  * shader. Also, if GL 4.0 is supported, use a geometry shader that emits
651  * primitives to multiple vertex streams. In this case the result of
652  * GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB has to match the sum of the
653  * number of primitives emitted to each particular vertex stream.
654  *
655  **/
656 class PipelineStatisticsQueryTestFunctional6 : public PipelineStatisticsQueryTestFunctionalBase
657 {
658 public:
659 	/* Public methods */
660 	PipelineStatisticsQueryTestFunctional6(deqp::Context& context);
661 
662 protected:
663 	/* Protected methods */
664 	void deinitObjects();
665 	bool executeTest(glw::GLenum current_query_target);
666 	void initObjects();
667 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
668 
669 private:
670 	/* Private fields */
671 	const unsigned int m_n_primitives_emitted_by_gs;
672 	const unsigned int m_n_streams_emitted_by_gs;
673 };
674 
675 /** Performs the following functional test:
676  *
677  * Using the basic outline with a program having a fragment shader check
678  * that FRAGMENT_SHADER_INVOCATIONS_ARB queries return a result greater
679  * than zero if at least one fragment gets rasterized.
680  *
681  **/
682 class PipelineStatisticsQueryTestFunctional7 : public PipelineStatisticsQueryTestFunctionalBase
683 {
684 public:
685 	/* Public methods */
686 	PipelineStatisticsQueryTestFunctional7(deqp::Context& context);
687 
688 protected:
689 	/* Protected methods */
690 	void deinitObjects();
691 	bool executeTest(glw::GLenum current_query_target);
692 	void initObjects();
693 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
694 };
695 
696 /** Performs the following functional test:
697  *
698  * Using the basic outline with a program having a compute shader check
699  * that COMPUTE_SHADER_INVOCATIONS_ARB queries return a result greater
700  * than zero if at least a single work group is submitted using one of the
701  * Dispatch* commands.
702  *
703  **/
704 class PipelineStatisticsQueryTestFunctional8 : public PipelineStatisticsQueryTestFunctionalBase
705 {
706 public:
707 	/* Public methods */
708 	PipelineStatisticsQueryTestFunctional8(deqp::Context& context);
709 
710 protected:
711 	/* Protected methods */
712 	void deinitObjects();
713 	bool executeTest(glw::GLenum current_query_target);
714 	void initObjects();
715 	bool shouldExecuteForQueryTarget(glw::GLenum query_target);
716 
717 private:
718 	/* Private methods */
719 	static bool queryCallbackDispatchCallHandler(void* pInstance);
720 
721 	/* Private fields */
722 	glw::GLuint  m_bo_dispatch_compute_indirect_args_offset;
723 	glw::GLuint  m_bo_id;
724 	unsigned int m_current_iteration;
725 };
726 
727 /** Test group which encapsulates all conformance tests for
728  *  GL_ARB_pipeline_statistics_query extension.
729  */
730 class PipelineStatisticsQueryTests : public deqp::TestCaseGroup
731 {
732 public:
733 	/* Public methods */
734 	PipelineStatisticsQueryTests(deqp::Context& context);
735 
736 	void init(void);
737 
738 private:
739 	PipelineStatisticsQueryTests(const PipelineStatisticsQueryTests& other);
740 	PipelineStatisticsQueryTests& operator=(const PipelineStatisticsQueryTests& other);
741 };
742 
743 } /* glcts namespace */
744 
745 #endif // _GL4CPIPELINESTATISTICSQUERYTESTS_HPP
746