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
41namespace glcts
42{
43class PipelineStatisticsQueryUtilities
44{
45public:
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 */
190		_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>
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 **/
355class PipelineStatisticsQueryTestAPICoverage1 : public deqp::TestCase
356{
357public:
358	/* Public methods */
359	PipelineStatisticsQueryTestAPICoverage1(deqp::Context& context);
360
361	virtual void						 deinit();
362	virtual tcu::TestNode::IterateResult iterate();
363
364private:
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 **/
384class PipelineStatisticsQueryTestAPICoverage2 : public deqp::TestCase
385{
386public:
387	/* Public methods */
388	PipelineStatisticsQueryTestAPICoverage2(deqp::Context& context);
389
390	virtual void						 deinit();
391	virtual tcu::TestNode::IterateResult iterate();
392
393private:
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 */
403class PipelineStatisticsQueryTestFunctionalBase : public deqp::TestCase
404{
405public:
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
412protected:
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 **/
470class PipelineStatisticsQueryTestFunctional1 : public PipelineStatisticsQueryTestFunctionalBase
471{
472public:
473	/* Public methods */
474	PipelineStatisticsQueryTestFunctional1(deqp::Context& context);
475
476protected:
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 **/
490class PipelineStatisticsQueryTestFunctional2 : public PipelineStatisticsQueryTestFunctionalBase
491{
492public:
493	/* Public methods */
494	PipelineStatisticsQueryTestFunctional2(deqp::Context& context);
495
496protected:
497	/* Protected methods */
498	void deinitObjects();
499	bool executeTest(glw::GLenum current_query_target);
500	void initObjects();
501
502private:
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 **/
569class PipelineStatisticsQueryTestFunctional3 : public PipelineStatisticsQueryTestFunctionalBase
570{
571public:
572	/* Public methods */
573	PipelineStatisticsQueryTestFunctional3(deqp::Context& context);
574
575protected:
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
582private:
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 **/
603class PipelineStatisticsQueryTestFunctional4 : public PipelineStatisticsQueryTestFunctionalBase
604{
605public:
606	/* Public methods */
607	PipelineStatisticsQueryTestFunctional4(deqp::Context& context);
608
609protected:
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 **/
627class PipelineStatisticsQueryTestFunctional5 : public PipelineStatisticsQueryTestFunctionalBase
628{
629public:
630	/* Public methods */
631	PipelineStatisticsQueryTestFunctional5(deqp::Context& context);
632
633protected:
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 **/
657class PipelineStatisticsQueryTestFunctional6 : public PipelineStatisticsQueryTestFunctionalBase
658{
659public:
660	/* Public methods */
661	PipelineStatisticsQueryTestFunctional6(deqp::Context& context);
662
663protected:
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
670private:
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 **/
683class PipelineStatisticsQueryTestFunctional7 : public PipelineStatisticsQueryTestFunctionalBase
684{
685public:
686	/* Public methods */
687	PipelineStatisticsQueryTestFunctional7(deqp::Context& context);
688
689protected:
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 **/
705class PipelineStatisticsQueryTestFunctional8 : public PipelineStatisticsQueryTestFunctionalBase
706{
707public:
708	/* Public methods */
709	PipelineStatisticsQueryTestFunctional8(deqp::Context& context);
710
711protected:
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
718private:
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 */
731class PipelineStatisticsQueryTests : public deqp::TestCaseGroup
732{
733public:
734	/* Public methods */
735	PipelineStatisticsQueryTests(deqp::Context& context);
736
737	void init(void);
738
739private:
740	PipelineStatisticsQueryTests(const PipelineStatisticsQueryTests& other);
741	PipelineStatisticsQueryTests& operator=(const PipelineStatisticsQueryTests& other);
742};
743
744} /* glcts namespace */
745
746#endif // _GL4CPIPELINESTATISTICSQUERYTESTS_HPP
747